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 <sys/resource.h>
23
24 #include <binder/IPCThreadState.h>
25 #include <media/AudioRecord.h>
26 #include <utils/Log.h>
27 #include <private/media/AudioTrackShared.h>
28 #include <media/IAudioFlinger.h>
29 #include <media/MediaAnalyticsItem.h>
30 #include <media/TypeConverter.h>
31
32 #define WAIT_PERIOD_MS 10
33
34 namespace android {
35 // ---------------------------------------------------------------------------
36
37 // static
getMinFrameCount(size_t * frameCount,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask)38 status_t AudioRecord::getMinFrameCount(
39 size_t* frameCount,
40 uint32_t sampleRate,
41 audio_format_t format,
42 audio_channel_mask_t channelMask)
43 {
44 if (frameCount == NULL) {
45 return BAD_VALUE;
46 }
47
48 size_t size;
49 status_t status = AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size);
50 if (status != NO_ERROR) {
51 ALOGE("AudioSystem could not query the input buffer size for sampleRate %u, format %#x, "
52 "channelMask %#x; status %d", sampleRate, format, channelMask, status);
53 return status;
54 }
55
56 // We double the size of input buffer for ping pong use of record buffer.
57 // Assumes audio_is_linear_pcm(format)
58 if ((*frameCount = (size * 2) / (audio_channel_count_from_in_mask(channelMask) *
59 audio_bytes_per_sample(format))) == 0) {
60 ALOGE("Unsupported configuration: sampleRate %u, format %#x, channelMask %#x",
61 sampleRate, format, channelMask);
62 return BAD_VALUE;
63 }
64
65 return NO_ERROR;
66 }
67
68 // ---------------------------------------------------------------------------
69
audioFormatTypeString(audio_format_t value)70 static std::string audioFormatTypeString(audio_format_t value) {
71 std::string formatType;
72 if (FormatConverter::toString(value, formatType)) {
73 return formatType;
74 }
75 char rawbuffer[16]; // room for "%d"
76 snprintf(rawbuffer, sizeof(rawbuffer), "%d", value);
77 return rawbuffer;
78 }
79
audioSourceString(audio_source_t value)80 static std::string audioSourceString(audio_source_t value) {
81 std::string source;
82 if (SourceTypeConverter::toString(value, source)) {
83 return source;
84 }
85 char rawbuffer[16]; // room for "%d"
86 snprintf(rawbuffer, sizeof(rawbuffer), "%d", value);
87 return rawbuffer;
88 }
89
gather(const AudioRecord * record)90 void AudioRecord::MediaMetrics::gather(const AudioRecord *record)
91 {
92 // key for media statistics is defined in the header
93 // attrs for media statistics
94 // NB: these are matched with public Java API constants defined
95 // in frameworks/base/media/java/android/media/AudioRecord.java
96 // These must be kept synchronized with the constants there.
97 static constexpr char kAudioRecordEncoding[] = "android.media.audiorecord.encoding";
98 static constexpr char kAudioRecordSource[] = "android.media.audiorecord.source";
99 static constexpr char kAudioRecordLatency[] = "android.media.audiorecord.latency";
100 static constexpr char kAudioRecordSampleRate[] = "android.media.audiorecord.samplerate";
101 static constexpr char kAudioRecordChannelCount[] = "android.media.audiorecord.channels";
102 static constexpr char kAudioRecordCreated[] = "android.media.audiorecord.createdMs";
103 static constexpr char kAudioRecordDuration[] = "android.media.audiorecord.durationMs";
104 static constexpr char kAudioRecordCount[] = "android.media.audiorecord.n";
105 static constexpr char kAudioRecordError[] = "android.media.audiorecord.errcode";
106 static constexpr char kAudioRecordErrorFunction[] = "android.media.audiorecord.errfunc";
107
108 // constructor guarantees mAnalyticsItem is valid
109
110 mAnalyticsItem->setInt32(kAudioRecordLatency, record->mLatency);
111 mAnalyticsItem->setInt32(kAudioRecordSampleRate, record->mSampleRate);
112 mAnalyticsItem->setInt32(kAudioRecordChannelCount, record->mChannelCount);
113 mAnalyticsItem->setCString(kAudioRecordEncoding,
114 audioFormatTypeString(record->mFormat).c_str());
115 mAnalyticsItem->setCString(kAudioRecordSource,
116 audioSourceString(record->mAttributes.source).c_str());
117
118 // log total duration recording, including anything currently running [and count].
119 nsecs_t active = 0;
120 if (mStartedNs != 0) {
121 active = systemTime() - mStartedNs;
122 }
123 mAnalyticsItem->setInt64(kAudioRecordDuration, (mDurationNs + active) / (1000 * 1000));
124 mAnalyticsItem->setInt32(kAudioRecordCount, mCount);
125
126 // XXX I don't know that this adds a lot of value, long term
127 if (mCreatedNs != 0) {
128 mAnalyticsItem->setInt64(kAudioRecordCreated, mCreatedNs / (1000 * 1000));
129 }
130
131 if (mLastError != NO_ERROR) {
132 mAnalyticsItem->setInt32(kAudioRecordError, mLastError);
133 mAnalyticsItem->setCString(kAudioRecordErrorFunction, mLastErrorFunc.c_str());
134 }
135 }
136
137 // hand the user a snapshot of the metrics.
getMetrics(MediaAnalyticsItem * & item)138 status_t AudioRecord::getMetrics(MediaAnalyticsItem * &item)
139 {
140 mMediaMetrics.gather(this);
141 MediaAnalyticsItem *tmp = mMediaMetrics.dup();
142 if (tmp == nullptr) {
143 return BAD_VALUE;
144 }
145 item = tmp;
146 return NO_ERROR;
147 }
148
AudioRecord(const String16 & opPackageName)149 AudioRecord::AudioRecord(const String16 &opPackageName)
150 : mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName),
151 mSessionId(AUDIO_SESSION_ALLOCATE),
152 mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT),
153 mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE)
154 {
155 }
156
AudioRecord(audio_source_t inputSource,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask,const String16 & opPackageName,size_t frameCount,callback_t cbf,void * user,uint32_t notificationFrames,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)157 AudioRecord::AudioRecord(
158 audio_source_t inputSource,
159 uint32_t sampleRate,
160 audio_format_t format,
161 audio_channel_mask_t channelMask,
162 const String16& opPackageName,
163 size_t frameCount,
164 callback_t cbf,
165 void* user,
166 uint32_t notificationFrames,
167 audio_session_t sessionId,
168 transfer_type transferType,
169 audio_input_flags_t flags,
170 uid_t uid,
171 pid_t pid,
172 const audio_attributes_t* pAttributes,
173 audio_port_handle_t selectedDeviceId)
174 : mActive(false),
175 mStatus(NO_INIT),
176 mOpPackageName(opPackageName),
177 mSessionId(AUDIO_SESSION_ALLOCATE),
178 mPreviousPriority(ANDROID_PRIORITY_NORMAL),
179 mPreviousSchedulingGroup(SP_DEFAULT),
180 mProxy(NULL)
181 {
182 (void)set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
183 notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
184 uid, pid, pAttributes, selectedDeviceId);
185 }
186
~AudioRecord()187 AudioRecord::~AudioRecord()
188 {
189 mMediaMetrics.gather(this);
190
191 if (mStatus == NO_ERROR) {
192 // Make sure that callback function exits in the case where
193 // it is looping on buffer empty condition in obtainBuffer().
194 // Otherwise the callback thread will never exit.
195 stop();
196 if (mAudioRecordThread != 0) {
197 mProxy->interrupt();
198 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h
199 mAudioRecordThread->requestExitAndWait();
200 mAudioRecordThread.clear();
201 }
202 // No lock here: worst case we remove a NULL callback which will be a nop
203 if (mDeviceCallback != 0 && mInput != AUDIO_IO_HANDLE_NONE) {
204 AudioSystem::removeAudioDeviceCallback(this, mInput);
205 }
206 IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this);
207 mAudioRecord.clear();
208 mCblkMemory.clear();
209 mBufferMemory.clear();
210 IPCThreadState::self()->flushCommands();
211 ALOGV("~AudioRecord, releasing session id %d",
212 mSessionId);
213 AudioSystem::releaseAudioSessionId(mSessionId, -1 /*pid*/);
214 }
215 }
216
set(audio_source_t inputSource,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask,size_t frameCount,callback_t cbf,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)217 status_t AudioRecord::set(
218 audio_source_t inputSource,
219 uint32_t sampleRate,
220 audio_format_t format,
221 audio_channel_mask_t channelMask,
222 size_t frameCount,
223 callback_t cbf,
224 void* user,
225 uint32_t notificationFrames,
226 bool threadCanCallJava,
227 audio_session_t sessionId,
228 transfer_type transferType,
229 audio_input_flags_t flags,
230 uid_t uid,
231 pid_t pid,
232 const audio_attributes_t* pAttributes,
233 audio_port_handle_t selectedDeviceId)
234 {
235 status_t status = NO_ERROR;
236 uint32_t channelCount;
237 pid_t callingPid;
238 pid_t myPid;
239
240 ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
241 "notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s "
242 "uid %d, pid %d",
243 inputSource, sampleRate, format, channelMask, frameCount, notificationFrames,
244 sessionId, transferType, flags, String8(mOpPackageName).string(), uid, pid);
245
246 mSelectedDeviceId = selectedDeviceId;
247
248 switch (transferType) {
249 case TRANSFER_DEFAULT:
250 if (cbf == NULL || threadCanCallJava) {
251 transferType = TRANSFER_SYNC;
252 } else {
253 transferType = TRANSFER_CALLBACK;
254 }
255 break;
256 case TRANSFER_CALLBACK:
257 if (cbf == NULL) {
258 ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL");
259 status = BAD_VALUE;
260 goto exit;
261 }
262 break;
263 case TRANSFER_OBTAIN:
264 case TRANSFER_SYNC:
265 break;
266 default:
267 ALOGE("Invalid transfer type %d", transferType);
268 status = BAD_VALUE;
269 goto exit;
270 }
271 mTransfer = transferType;
272
273 // invariant that mAudioRecord != 0 is true only after set() returns successfully
274 if (mAudioRecord != 0) {
275 ALOGE("Track already in use");
276 status = INVALID_OPERATION;
277 goto exit;
278 }
279
280 if (pAttributes == NULL) {
281 memset(&mAttributes, 0, sizeof(audio_attributes_t));
282 mAttributes.source = inputSource;
283 } else {
284 // stream type shouldn't be looked at, this track has audio attributes
285 memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));
286 ALOGV("Building AudioRecord with attributes: source=%d flags=0x%x tags=[%s]",
287 mAttributes.source, mAttributes.flags, mAttributes.tags);
288 }
289
290 mSampleRate = sampleRate;
291
292 // these below should probably come from the audioFlinger too...
293 if (format == AUDIO_FORMAT_DEFAULT) {
294 format = AUDIO_FORMAT_PCM_16_BIT;
295 }
296
297 // validate parameters
298 // AudioFlinger capture only supports linear PCM
299 if (!audio_is_valid_format(format) || !audio_is_linear_pcm(format)) {
300 ALOGE("Format %#x is not linear pcm", format);
301 status = BAD_VALUE;
302 goto exit;
303 }
304 mFormat = format;
305
306 if (!audio_is_input_channel(channelMask)) {
307 ALOGE("Invalid channel mask %#x", channelMask);
308 status = BAD_VALUE;
309 goto exit;
310 }
311 mChannelMask = channelMask;
312 channelCount = audio_channel_count_from_in_mask(channelMask);
313 mChannelCount = channelCount;
314
315 if (audio_is_linear_pcm(format)) {
316 mFrameSize = channelCount * audio_bytes_per_sample(format);
317 } else {
318 mFrameSize = sizeof(uint8_t);
319 }
320
321 // mFrameCount is initialized in createRecord_l
322 mReqFrameCount = frameCount;
323
324 mNotificationFramesReq = notificationFrames;
325 // mNotificationFramesAct is initialized in createRecord_l
326
327 mSessionId = sessionId;
328 ALOGV("set(): mSessionId %d", mSessionId);
329
330 callingPid = IPCThreadState::self()->getCallingPid();
331 myPid = getpid();
332 if (uid == AUDIO_UID_INVALID || (callingPid != myPid)) {
333 mClientUid = IPCThreadState::self()->getCallingUid();
334 } else {
335 mClientUid = uid;
336 }
337 if (pid == -1 || (callingPid != myPid)) {
338 mClientPid = callingPid;
339 } else {
340 mClientPid = pid;
341 }
342
343 mOrigFlags = mFlags = flags;
344 mCbf = cbf;
345
346 if (cbf != NULL) {
347 mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava);
348 mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO);
349 // thread begins in paused state, and will not reference us until start()
350 }
351
352 // create the IAudioRecord
353 status = createRecord_l(0 /*epoch*/, mOpPackageName);
354
355 if (status != NO_ERROR) {
356 if (mAudioRecordThread != 0) {
357 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h
358 mAudioRecordThread->requestExitAndWait();
359 mAudioRecordThread.clear();
360 }
361 goto exit;
362 }
363
364 mUserData = user;
365 // TODO: add audio hardware input latency here
366 mLatency = (1000LL * mFrameCount) / mSampleRate;
367 mMarkerPosition = 0;
368 mMarkerReached = false;
369 mNewPosition = 0;
370 mUpdatePeriod = 0;
371 AudioSystem::acquireAudioSessionId(mSessionId, -1);
372 mSequence = 1;
373 mObservedSequence = mSequence;
374 mInOverrun = false;
375 mFramesRead = 0;
376 mFramesReadServerOffset = 0;
377
378 exit:
379 mStatus = status;
380 if (status != NO_ERROR) {
381 mMediaMetrics.markError(status, __FUNCTION__);
382 }
383 return status;
384 }
385
386 // -------------------------------------------------------------------------
387
start(AudioSystem::sync_event_t event,audio_session_t triggerSession)388 status_t AudioRecord::start(AudioSystem::sync_event_t event, audio_session_t triggerSession)
389 {
390 ALOGV("start, sync event %d trigger session %d", event, triggerSession);
391
392 AutoMutex lock(mLock);
393 if (mActive) {
394 return NO_ERROR;
395 }
396
397 // discard data in buffer
398 const uint32_t framesFlushed = mProxy->flush();
399 mFramesReadServerOffset -= mFramesRead + framesFlushed;
400 mFramesRead = 0;
401 mProxy->clearTimestamp(); // timestamp is invalid until next server push
402
403 // reset current position as seen by client to 0
404 mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition());
405 // force refresh of remaining frames by processAudioBuffer() as last
406 // read before stop could be partial.
407 mRefreshRemaining = true;
408
409 mNewPosition = mProxy->getPosition() + mUpdatePeriod;
410 int32_t flags = android_atomic_acquire_load(&mCblk->mFlags);
411
412 // we reactivate markers (mMarkerPosition != 0) as the position is reset to 0.
413 // This is legacy behavior. This is not done in stop() to avoid a race condition
414 // where the last marker event is issued twice.
415 mMarkerReached = false;
416 mActive = true;
417
418 status_t status = NO_ERROR;
419 if (!(flags & CBLK_INVALID)) {
420 status = mAudioRecord->start(event, triggerSession).transactionError();
421 if (status == DEAD_OBJECT) {
422 flags |= CBLK_INVALID;
423 }
424 }
425 if (flags & CBLK_INVALID) {
426 status = restoreRecord_l("start");
427 }
428
429 if (status != NO_ERROR) {
430 mActive = false;
431 ALOGE("start() status %d", status);
432 } else {
433 sp<AudioRecordThread> t = mAudioRecordThread;
434 if (t != 0) {
435 t->resume();
436 } else {
437 mPreviousPriority = getpriority(PRIO_PROCESS, 0);
438 get_sched_policy(0, &mPreviousSchedulingGroup);
439 androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
440 }
441
442 // we've successfully started, log that time
443 mMediaMetrics.logStart(systemTime());
444 }
445
446 if (status != NO_ERROR) {
447 mMediaMetrics.markError(status, __FUNCTION__);
448 }
449 return status;
450 }
451
stop()452 void AudioRecord::stop()
453 {
454 AutoMutex lock(mLock);
455 if (!mActive) {
456 return;
457 }
458
459 mActive = false;
460 mProxy->interrupt();
461 mAudioRecord->stop();
462
463 // Note: legacy handling - stop does not clear record marker and
464 // periodic update position; we update those on start().
465
466 sp<AudioRecordThread> t = mAudioRecordThread;
467 if (t != 0) {
468 t->pause();
469 } else {
470 setpriority(PRIO_PROCESS, 0, mPreviousPriority);
471 set_sched_policy(0, mPreviousSchedulingGroup);
472 }
473
474 // we've successfully started, log that time
475 mMediaMetrics.logStop(systemTime());
476 }
477
stopped() const478 bool AudioRecord::stopped() const
479 {
480 AutoMutex lock(mLock);
481 return !mActive;
482 }
483
setMarkerPosition(uint32_t marker)484 status_t AudioRecord::setMarkerPosition(uint32_t marker)
485 {
486 // The only purpose of setting marker position is to get a callback
487 if (mCbf == NULL) {
488 return INVALID_OPERATION;
489 }
490
491 AutoMutex lock(mLock);
492 mMarkerPosition = marker;
493 mMarkerReached = false;
494
495 sp<AudioRecordThread> t = mAudioRecordThread;
496 if (t != 0) {
497 t->wake();
498 }
499 return NO_ERROR;
500 }
501
getMarkerPosition(uint32_t * marker) const502 status_t AudioRecord::getMarkerPosition(uint32_t *marker) const
503 {
504 if (marker == NULL) {
505 return BAD_VALUE;
506 }
507
508 AutoMutex lock(mLock);
509 mMarkerPosition.getValue(marker);
510
511 return NO_ERROR;
512 }
513
setPositionUpdatePeriod(uint32_t updatePeriod)514 status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
515 {
516 // The only purpose of setting position update period is to get a callback
517 if (mCbf == NULL) {
518 return INVALID_OPERATION;
519 }
520
521 AutoMutex lock(mLock);
522 mNewPosition = mProxy->getPosition() + updatePeriod;
523 mUpdatePeriod = updatePeriod;
524
525 sp<AudioRecordThread> t = mAudioRecordThread;
526 if (t != 0) {
527 t->wake();
528 }
529 return NO_ERROR;
530 }
531
getPositionUpdatePeriod(uint32_t * updatePeriod) const532 status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const
533 {
534 if (updatePeriod == NULL) {
535 return BAD_VALUE;
536 }
537
538 AutoMutex lock(mLock);
539 *updatePeriod = mUpdatePeriod;
540
541 return NO_ERROR;
542 }
543
getPosition(uint32_t * position) const544 status_t AudioRecord::getPosition(uint32_t *position) const
545 {
546 if (position == NULL) {
547 return BAD_VALUE;
548 }
549
550 AutoMutex lock(mLock);
551 mProxy->getPosition().getValue(position);
552
553 return NO_ERROR;
554 }
555
getInputFramesLost() const556 uint32_t AudioRecord::getInputFramesLost() const
557 {
558 // no need to check mActive, because if inactive this will return 0, which is what we want
559 return AudioSystem::getInputFramesLost(getInputPrivate());
560 }
561
getTimestamp(ExtendedTimestamp * timestamp)562 status_t AudioRecord::getTimestamp(ExtendedTimestamp *timestamp)
563 {
564 if (timestamp == nullptr) {
565 return BAD_VALUE;
566 }
567 AutoMutex lock(mLock);
568 status_t status = mProxy->getTimestamp(timestamp);
569 if (status == OK) {
570 timestamp->mPosition[ExtendedTimestamp::LOCATION_CLIENT] = mFramesRead;
571 timestamp->mTimeNs[ExtendedTimestamp::LOCATION_CLIENT] = 0;
572 // server side frame offset in case AudioRecord has been restored.
573 for (int i = ExtendedTimestamp::LOCATION_SERVER;
574 i < ExtendedTimestamp::LOCATION_MAX; ++i) {
575 if (timestamp->mTimeNs[i] >= 0) {
576 timestamp->mPosition[i] += mFramesReadServerOffset;
577 }
578 }
579 }
580 return status;
581 }
582
583 // ---- Explicit Routing ---------------------------------------------------
setInputDevice(audio_port_handle_t deviceId)584 status_t AudioRecord::setInputDevice(audio_port_handle_t deviceId) {
585 AutoMutex lock(mLock);
586 if (mSelectedDeviceId != deviceId) {
587 mSelectedDeviceId = deviceId;
588 if (mStatus == NO_ERROR) {
589 // stop capture so that audio policy manager does not reject the new instance start request
590 // as only one capture can be active at a time.
591 if (mAudioRecord != 0 && mActive) {
592 mAudioRecord->stop();
593 }
594 android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
595 mProxy->interrupt();
596 }
597 }
598 return NO_ERROR;
599 }
600
getInputDevice()601 audio_port_handle_t AudioRecord::getInputDevice() {
602 AutoMutex lock(mLock);
603 return mSelectedDeviceId;
604 }
605
606 // must be called with mLock held
updateRoutedDeviceId_l()607 void AudioRecord::updateRoutedDeviceId_l()
608 {
609 // if the record is inactive, do not update actual device as the input stream maybe routed
610 // from a device not relevant to this client because of other active use cases.
611 if (!mActive) {
612 return;
613 }
614 if (mInput != AUDIO_IO_HANDLE_NONE) {
615 audio_port_handle_t deviceId = AudioSystem::getDeviceIdForIo(mInput);
616 if (deviceId != AUDIO_PORT_HANDLE_NONE) {
617 mRoutedDeviceId = deviceId;
618 }
619 }
620 }
621
getRoutedDeviceId()622 audio_port_handle_t AudioRecord::getRoutedDeviceId() {
623 AutoMutex lock(mLock);
624 updateRoutedDeviceId_l();
625 return mRoutedDeviceId;
626 }
627
dump(int fd,const Vector<String16> & args __unused) const628 status_t AudioRecord::dump(int fd, const Vector<String16>& args __unused) const
629 {
630 String8 result;
631
632 result.append(" AudioRecord::dump\n");
633 result.appendFormat(" status(%d), active(%d), session Id(%d)\n",
634 mStatus, mActive, mSessionId);
635 result.appendFormat(" flags(%#x), req. flags(%#x), audio source(%d)\n",
636 mFlags, mOrigFlags, mAttributes.source);
637 result.appendFormat(" format(%#x), channel mask(%#x), channel count(%u), sample rate(%u)\n",
638 mFormat, mChannelMask, mChannelCount, mSampleRate);
639 result.appendFormat(" frame count(%zu), req. frame count(%zu)\n",
640 mFrameCount, mReqFrameCount);
641 result.appendFormat(" notif. frame count(%u), req. notif. frame count(%u)\n",
642 mNotificationFramesAct, mNotificationFramesReq);
643 result.appendFormat(" input(%d), latency(%u), selected device Id(%d), routed device Id(%d)\n",
644 mInput, mLatency, mSelectedDeviceId, mRoutedDeviceId);
645 ::write(fd, result.string(), result.size());
646 return NO_ERROR;
647 }
648
649 // -------------------------------------------------------------------------
650 // TODO Move this macro to a common header file for enum to string conversion in audio framework.
651 #define MEDIA_CASE_ENUM(name) case name: return #name
convertTransferToText(transfer_type transferType)652 const char * AudioRecord::convertTransferToText(transfer_type transferType) {
653 switch (transferType) {
654 MEDIA_CASE_ENUM(TRANSFER_DEFAULT);
655 MEDIA_CASE_ENUM(TRANSFER_CALLBACK);
656 MEDIA_CASE_ENUM(TRANSFER_OBTAIN);
657 MEDIA_CASE_ENUM(TRANSFER_SYNC);
658 default:
659 return "UNRECOGNIZED";
660 }
661 }
662
663 // must be called with mLock held
createRecord_l(const Modulo<uint32_t> & epoch,const String16 & opPackageName)664 status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch, const String16& opPackageName)
665 {
666 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
667 IAudioFlinger::CreateRecordInput input;
668 IAudioFlinger::CreateRecordOutput output;
669 audio_session_t originalSessionId;
670 sp<media::IAudioRecord> record;
671 void *iMemPointer;
672 audio_track_cblk_t* cblk;
673 status_t status;
674
675 if (audioFlinger == 0) {
676 ALOGE("Could not get audioflinger");
677 status = NO_INIT;
678 goto exit;
679 }
680
681 // mFlags (not mOrigFlags) is modified depending on whether fast request is accepted.
682 // After fast request is denied, we will request again if IAudioRecord is re-created.
683
684 // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
685 // we must release it ourselves if anything goes wrong.
686
687 // Client can only express a preference for FAST. Server will perform additional tests.
688 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
689 bool useCaseAllowed =
690 // any of these use cases:
691 // use case 1: callback transfer mode
692 (mTransfer == TRANSFER_CALLBACK) ||
693 // use case 2: blocking read mode
694 // The default buffer capacity at 48 kHz is 2048 frames, or ~42.6 ms.
695 // That's enough for double-buffering with our standard 20 ms rule of thumb for
696 // the minimum period of a non-SCHED_FIFO thread.
697 // This is needed so that AAudio apps can do a low latency non-blocking read from a
698 // callback running with SCHED_FIFO.
699 (mTransfer == TRANSFER_SYNC) ||
700 // use case 3: obtain/release mode
701 (mTransfer == TRANSFER_OBTAIN);
702 if (!useCaseAllowed) {
703 ALOGW("AUDIO_INPUT_FLAG_FAST denied, incompatible transfer = %s",
704 convertTransferToText(mTransfer));
705 mFlags = (audio_input_flags_t) (mFlags & ~(AUDIO_INPUT_FLAG_FAST |
706 AUDIO_INPUT_FLAG_RAW));
707 }
708 }
709
710 input.attr = mAttributes;
711 input.config.sample_rate = mSampleRate;
712 input.config.channel_mask = mChannelMask;
713 input.config.format = mFormat;
714 input.clientInfo.clientUid = mClientUid;
715 input.clientInfo.clientPid = mClientPid;
716 input.clientInfo.clientTid = -1;
717 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
718 if (mAudioRecordThread != 0) {
719 input.clientInfo.clientTid = mAudioRecordThread->getTid();
720 }
721 }
722 input.opPackageName = opPackageName;
723
724 input.flags = mFlags;
725 // The notification frame count is the period between callbacks, as suggested by the client
726 // but moderated by the server. For record, the calculations are done entirely on server side.
727 input.frameCount = mReqFrameCount;
728 input.notificationFrameCount = mNotificationFramesReq;
729 input.selectedDeviceId = mSelectedDeviceId;
730 input.sessionId = mSessionId;
731 originalSessionId = mSessionId;
732
733 record = audioFlinger->createRecord(input,
734 output,
735 &status);
736
737 if (status != NO_ERROR) {
738 ALOGE("AudioFlinger could not create record track, status: %d", status);
739 goto exit;
740 }
741 ALOG_ASSERT(record != 0);
742
743 // AudioFlinger now owns the reference to the I/O handle,
744 // so we are no longer responsible for releasing it.
745
746 mAwaitBoost = false;
747 if (output.flags & AUDIO_INPUT_FLAG_FAST) {
748 ALOGI("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu -> %zu",
749 mReqFrameCount, output.frameCount);
750 mAwaitBoost = true;
751 }
752 mFlags = output.flags;
753 mRoutedDeviceId = output.selectedDeviceId;
754 mSessionId = output.sessionId;
755 mSampleRate = output.sampleRate;
756
757 if (output.cblk == 0) {
758 ALOGE("Could not get control block");
759 status = NO_INIT;
760 goto exit;
761 }
762 iMemPointer = output.cblk ->pointer();
763 if (iMemPointer == NULL) {
764 ALOGE("Could not get control block pointer");
765 status = NO_INIT;
766 goto exit;
767 }
768 cblk = static_cast<audio_track_cblk_t*>(iMemPointer);
769
770 // Starting address of buffers in shared memory.
771 // The buffers are either immediately after the control block,
772 // or in a separate area at discretion of server.
773 void *buffers;
774 if (output.buffers == 0) {
775 buffers = cblk + 1;
776 } else {
777 buffers = output.buffers->pointer();
778 if (buffers == NULL) {
779 ALOGE("Could not get buffer pointer");
780 status = NO_INIT;
781 goto exit;
782 }
783 }
784
785 // invariant that mAudioRecord != 0 is true only after set() returns successfully
786 if (mAudioRecord != 0) {
787 IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this);
788 mDeathNotifier.clear();
789 }
790 mAudioRecord = record;
791 mCblkMemory = output.cblk;
792 mBufferMemory = output.buffers;
793 IPCThreadState::self()->flushCommands();
794
795 mCblk = cblk;
796 // note that output.frameCount is the (possibly revised) value of mReqFrameCount
797 if (output.frameCount < mReqFrameCount || (mReqFrameCount == 0 && output.frameCount == 0)) {
798 ALOGW("Requested frameCount %zu but received frameCount %zu",
799 mReqFrameCount, output.frameCount);
800 }
801
802 // Make sure that application is notified with sufficient margin before overrun.
803 // The computation is done on server side.
804 if (mNotificationFramesReq > 0 && output.notificationFrameCount != mNotificationFramesReq) {
805 ALOGW("Server adjusted notificationFrames from %u to %zu for frameCount %zu",
806 mNotificationFramesReq, output.notificationFrameCount, output.frameCount);
807 }
808 mNotificationFramesAct = (uint32_t)output.notificationFrameCount;
809
810 //mInput != input includes the case where mInput == AUDIO_IO_HANDLE_NONE for first creation
811 if (mDeviceCallback != 0 && mInput != output.inputId) {
812 if (mInput != AUDIO_IO_HANDLE_NONE) {
813 AudioSystem::removeAudioDeviceCallback(this, mInput);
814 }
815 AudioSystem::addAudioDeviceCallback(this, output.inputId);
816 }
817
818 // We retain a copy of the I/O handle, but don't own the reference
819 mInput = output.inputId;
820 mRefreshRemaining = true;
821
822 mFrameCount = output.frameCount;
823 // If IAudioRecord is re-created, don't let the requested frameCount
824 // decrease. This can confuse clients that cache frameCount().
825 if (mFrameCount > mReqFrameCount) {
826 mReqFrameCount = mFrameCount;
827 }
828
829 // update proxy
830 mProxy = new AudioRecordClientProxy(cblk, buffers, mFrameCount, mFrameSize);
831 mProxy->setEpoch(epoch);
832 mProxy->setMinimum(mNotificationFramesAct);
833
834 mDeathNotifier = new DeathNotifier(this);
835 IInterface::asBinder(mAudioRecord)->linkToDeath(mDeathNotifier, this);
836
837 exit:
838 mStatus = status;
839 // sp<IAudioTrack> track destructor will cause releaseOutput() to be called by AudioFlinger
840 return status;
841 }
842
obtainBuffer(Buffer * audioBuffer,int32_t waitCount,size_t * nonContig)843 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount, size_t *nonContig)
844 {
845 if (audioBuffer == NULL) {
846 if (nonContig != NULL) {
847 *nonContig = 0;
848 }
849 return BAD_VALUE;
850 }
851 if (mTransfer != TRANSFER_OBTAIN) {
852 audioBuffer->frameCount = 0;
853 audioBuffer->size = 0;
854 audioBuffer->raw = NULL;
855 if (nonContig != NULL) {
856 *nonContig = 0;
857 }
858 return INVALID_OPERATION;
859 }
860
861 const struct timespec *requested;
862 struct timespec timeout;
863 if (waitCount == -1) {
864 requested = &ClientProxy::kForever;
865 } else if (waitCount == 0) {
866 requested = &ClientProxy::kNonBlocking;
867 } else if (waitCount > 0) {
868 long long ms = WAIT_PERIOD_MS * (long long) waitCount;
869 timeout.tv_sec = ms / 1000;
870 timeout.tv_nsec = (int) (ms % 1000) * 1000000;
871 requested = &timeout;
872 } else {
873 ALOGE("%s invalid waitCount %d", __func__, waitCount);
874 requested = NULL;
875 }
876 return obtainBuffer(audioBuffer, requested, NULL /*elapsed*/, nonContig);
877 }
878
obtainBuffer(Buffer * audioBuffer,const struct timespec * requested,struct timespec * elapsed,size_t * nonContig)879 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *requested,
880 struct timespec *elapsed, size_t *nonContig)
881 {
882 // previous and new IAudioRecord sequence numbers are used to detect track re-creation
883 uint32_t oldSequence = 0;
884 uint32_t newSequence;
885
886 Proxy::Buffer buffer;
887 status_t status = NO_ERROR;
888
889 static const int32_t kMaxTries = 5;
890 int32_t tryCounter = kMaxTries;
891
892 do {
893 // obtainBuffer() is called with mutex unlocked, so keep extra references to these fields to
894 // keep them from going away if another thread re-creates the track during obtainBuffer()
895 sp<AudioRecordClientProxy> proxy;
896 sp<IMemory> iMem;
897 sp<IMemory> bufferMem;
898 {
899 // start of lock scope
900 AutoMutex lock(mLock);
901
902 newSequence = mSequence;
903 // did previous obtainBuffer() fail due to media server death or voluntary invalidation?
904 if (status == DEAD_OBJECT) {
905 // re-create track, unless someone else has already done so
906 if (newSequence == oldSequence) {
907 status = restoreRecord_l("obtainBuffer");
908 if (status != NO_ERROR) {
909 buffer.mFrameCount = 0;
910 buffer.mRaw = NULL;
911 buffer.mNonContig = 0;
912 break;
913 }
914 }
915 }
916 oldSequence = newSequence;
917
918 // Keep the extra references
919 proxy = mProxy;
920 iMem = mCblkMemory;
921 bufferMem = mBufferMemory;
922
923 // Non-blocking if track is stopped
924 if (!mActive) {
925 requested = &ClientProxy::kNonBlocking;
926 }
927
928 } // end of lock scope
929
930 buffer.mFrameCount = audioBuffer->frameCount;
931 // FIXME starts the requested timeout and elapsed over from scratch
932 status = proxy->obtainBuffer(&buffer, requested, elapsed);
933
934 } while ((status == DEAD_OBJECT) && (tryCounter-- > 0));
935
936 audioBuffer->frameCount = buffer.mFrameCount;
937 audioBuffer->size = buffer.mFrameCount * mFrameSize;
938 audioBuffer->raw = buffer.mRaw;
939 if (nonContig != NULL) {
940 *nonContig = buffer.mNonContig;
941 }
942 return status;
943 }
944
releaseBuffer(const Buffer * audioBuffer)945 void AudioRecord::releaseBuffer(const Buffer* audioBuffer)
946 {
947 // FIXME add error checking on mode, by adding an internal version
948
949 size_t stepCount = audioBuffer->size / mFrameSize;
950 if (stepCount == 0) {
951 return;
952 }
953
954 Proxy::Buffer buffer;
955 buffer.mFrameCount = stepCount;
956 buffer.mRaw = audioBuffer->raw;
957
958 AutoMutex lock(mLock);
959 mInOverrun = false;
960 mProxy->releaseBuffer(&buffer);
961
962 // the server does not automatically disable recorder on overrun, so no need to restart
963 }
964
getInputPrivate() const965 audio_io_handle_t AudioRecord::getInputPrivate() const
966 {
967 AutoMutex lock(mLock);
968 return mInput;
969 }
970
971 // -------------------------------------------------------------------------
972
read(void * buffer,size_t userSize,bool blocking)973 ssize_t AudioRecord::read(void* buffer, size_t userSize, bool blocking)
974 {
975 if (mTransfer != TRANSFER_SYNC) {
976 return INVALID_OPERATION;
977 }
978
979 if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
980 // sanity-check. user is most-likely passing an error code, and it would
981 // make the return value ambiguous (actualSize vs error).
982 ALOGE("AudioRecord::read(buffer=%p, size=%zu (%zu)", buffer, userSize, userSize);
983 return BAD_VALUE;
984 }
985
986 ssize_t read = 0;
987 Buffer audioBuffer;
988
989 while (userSize >= mFrameSize) {
990 audioBuffer.frameCount = userSize / mFrameSize;
991
992 status_t err = obtainBuffer(&audioBuffer,
993 blocking ? &ClientProxy::kForever : &ClientProxy::kNonBlocking);
994 if (err < 0) {
995 if (read > 0) {
996 break;
997 }
998 if (err == TIMED_OUT || err == -EINTR) {
999 err = WOULD_BLOCK;
1000 }
1001 return ssize_t(err);
1002 }
1003
1004 size_t bytesRead = audioBuffer.size;
1005 memcpy(buffer, audioBuffer.i8, bytesRead);
1006 buffer = ((char *) buffer) + bytesRead;
1007 userSize -= bytesRead;
1008 read += bytesRead;
1009
1010 releaseBuffer(&audioBuffer);
1011 }
1012 if (read > 0) {
1013 mFramesRead += read / mFrameSize;
1014 // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time.
1015 }
1016 return read;
1017 }
1018
1019 // -------------------------------------------------------------------------
1020
processAudioBuffer()1021 nsecs_t AudioRecord::processAudioBuffer()
1022 {
1023 mLock.lock();
1024 if (mAwaitBoost) {
1025 mAwaitBoost = false;
1026 mLock.unlock();
1027 static const int32_t kMaxTries = 5;
1028 int32_t tryCounter = kMaxTries;
1029 uint32_t pollUs = 10000;
1030 do {
1031 int policy = sched_getscheduler(0) & ~SCHED_RESET_ON_FORK;
1032 if (policy == SCHED_FIFO || policy == SCHED_RR) {
1033 break;
1034 }
1035 usleep(pollUs);
1036 pollUs <<= 1;
1037 } while (tryCounter-- > 0);
1038 if (tryCounter < 0) {
1039 ALOGE("did not receive expected priority boost on time");
1040 }
1041 // Run again immediately
1042 return 0;
1043 }
1044
1045 // Can only reference mCblk while locked
1046 int32_t flags = android_atomic_and(~CBLK_OVERRUN, &mCblk->mFlags);
1047
1048 // Check for track invalidation
1049 if (flags & CBLK_INVALID) {
1050 (void) restoreRecord_l("processAudioBuffer");
1051 mLock.unlock();
1052 // Run again immediately, but with a new IAudioRecord
1053 return 0;
1054 }
1055
1056 bool active = mActive;
1057
1058 // Manage overrun callback, must be done under lock to avoid race with releaseBuffer()
1059 bool newOverrun = false;
1060 if (flags & CBLK_OVERRUN) {
1061 if (!mInOverrun) {
1062 mInOverrun = true;
1063 newOverrun = true;
1064 }
1065 }
1066
1067 // Get current position of server
1068 Modulo<uint32_t> position(mProxy->getPosition());
1069
1070 // Manage marker callback
1071 bool markerReached = false;
1072 Modulo<uint32_t> markerPosition(mMarkerPosition);
1073 // FIXME fails for wraparound, need 64 bits
1074 if (!mMarkerReached && markerPosition.value() > 0 && position >= markerPosition) {
1075 mMarkerReached = markerReached = true;
1076 }
1077
1078 // Determine the number of new position callback(s) that will be needed, while locked
1079 size_t newPosCount = 0;
1080 Modulo<uint32_t> newPosition(mNewPosition);
1081 uint32_t updatePeriod = mUpdatePeriod;
1082 // FIXME fails for wraparound, need 64 bits
1083 if (updatePeriod > 0 && position >= newPosition) {
1084 newPosCount = ((position - newPosition).value() / updatePeriod) + 1;
1085 mNewPosition += updatePeriod * newPosCount;
1086 }
1087
1088 // Cache other fields that will be needed soon
1089 uint32_t notificationFrames = mNotificationFramesAct;
1090 if (mRefreshRemaining) {
1091 mRefreshRemaining = false;
1092 mRemainingFrames = notificationFrames;
1093 mRetryOnPartialBuffer = false;
1094 }
1095 size_t misalignment = mProxy->getMisalignment();
1096 uint32_t sequence = mSequence;
1097
1098 // These fields don't need to be cached, because they are assigned only by set():
1099 // mTransfer, mCbf, mUserData, mSampleRate, mFrameSize
1100
1101 mLock.unlock();
1102
1103 // perform callbacks while unlocked
1104 if (newOverrun) {
1105 mCbf(EVENT_OVERRUN, mUserData, NULL);
1106 }
1107 if (markerReached) {
1108 mCbf(EVENT_MARKER, mUserData, &markerPosition);
1109 }
1110 while (newPosCount > 0) {
1111 size_t temp = newPosition.value(); // FIXME size_t != uint32_t
1112 mCbf(EVENT_NEW_POS, mUserData, &temp);
1113 newPosition += updatePeriod;
1114 newPosCount--;
1115 }
1116 if (mObservedSequence != sequence) {
1117 mObservedSequence = sequence;
1118 mCbf(EVENT_NEW_IAUDIORECORD, mUserData, NULL);
1119 }
1120
1121 // if inactive, then don't run me again until re-started
1122 if (!active) {
1123 return NS_INACTIVE;
1124 }
1125
1126 // Compute the estimated time until the next timed event (position, markers)
1127 uint32_t minFrames = ~0;
1128 if (!markerReached && position < markerPosition) {
1129 minFrames = (markerPosition - position).value();
1130 }
1131 if (updatePeriod > 0) {
1132 uint32_t remaining = (newPosition - position).value();
1133 if (remaining < minFrames) {
1134 minFrames = remaining;
1135 }
1136 }
1137
1138 // If > 0, poll periodically to recover from a stuck server. A good value is 2.
1139 static const uint32_t kPoll = 0;
1140 if (kPoll > 0 && mTransfer == TRANSFER_CALLBACK && kPoll * notificationFrames < minFrames) {
1141 minFrames = kPoll * notificationFrames;
1142 }
1143
1144 // Convert frame units to time units
1145 nsecs_t ns = NS_WHENEVER;
1146 if (minFrames != (uint32_t) ~0) {
1147 // This "fudge factor" avoids soaking CPU, and compensates for late progress by server
1148 static const nsecs_t kFudgeNs = 10000000LL; // 10 ms
1149 ns = ((minFrames * 1000000000LL) / mSampleRate) + kFudgeNs;
1150 }
1151
1152 // If not supplying data by EVENT_MORE_DATA, then we're done
1153 if (mTransfer != TRANSFER_CALLBACK) {
1154 return ns;
1155 }
1156
1157 struct timespec timeout;
1158 const struct timespec *requested = &ClientProxy::kForever;
1159 if (ns != NS_WHENEVER) {
1160 timeout.tv_sec = ns / 1000000000LL;
1161 timeout.tv_nsec = ns % 1000000000LL;
1162 ALOGV("timeout %ld.%03d", timeout.tv_sec, (int) timeout.tv_nsec / 1000000);
1163 requested = &timeout;
1164 }
1165
1166 size_t readFrames = 0;
1167 while (mRemainingFrames > 0) {
1168
1169 Buffer audioBuffer;
1170 audioBuffer.frameCount = mRemainingFrames;
1171 size_t nonContig;
1172 status_t err = obtainBuffer(&audioBuffer, requested, NULL, &nonContig);
1173 LOG_ALWAYS_FATAL_IF((err != NO_ERROR) != (audioBuffer.frameCount == 0),
1174 "obtainBuffer() err=%d frameCount=%zu", err, audioBuffer.frameCount);
1175 requested = &ClientProxy::kNonBlocking;
1176 size_t avail = audioBuffer.frameCount + nonContig;
1177 ALOGV("obtainBuffer(%u) returned %zu = %zu + %zu err %d",
1178 mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err);
1179 if (err != NO_ERROR) {
1180 if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR) {
1181 break;
1182 }
1183 ALOGE("Error %d obtaining an audio buffer, giving up.", err);
1184 return NS_NEVER;
1185 }
1186
1187 if (mRetryOnPartialBuffer) {
1188 mRetryOnPartialBuffer = false;
1189 if (avail < mRemainingFrames) {
1190 int64_t myns = ((mRemainingFrames - avail) *
1191 1100000000LL) / mSampleRate;
1192 if (ns < 0 || myns < ns) {
1193 ns = myns;
1194 }
1195 return ns;
1196 }
1197 }
1198
1199 size_t reqSize = audioBuffer.size;
1200 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
1201 size_t readSize = audioBuffer.size;
1202
1203 // Sanity check on returned size
1204 if (ssize_t(readSize) < 0 || readSize > reqSize) {
1205 ALOGE("EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
1206 reqSize, ssize_t(readSize));
1207 return NS_NEVER;
1208 }
1209
1210 if (readSize == 0) {
1211 // The callback is done consuming buffers
1212 // Keep this thread going to handle timed events and
1213 // still try to provide more data in intervals of WAIT_PERIOD_MS
1214 // but don't just loop and block the CPU, so wait
1215 return WAIT_PERIOD_MS * 1000000LL;
1216 }
1217
1218 size_t releasedFrames = readSize / mFrameSize;
1219 audioBuffer.frameCount = releasedFrames;
1220 mRemainingFrames -= releasedFrames;
1221 if (misalignment >= releasedFrames) {
1222 misalignment -= releasedFrames;
1223 } else {
1224 misalignment = 0;
1225 }
1226
1227 releaseBuffer(&audioBuffer);
1228 readFrames += releasedFrames;
1229
1230 // FIXME here is where we would repeat EVENT_MORE_DATA again on same advanced buffer
1231 // if callback doesn't like to accept the full chunk
1232 if (readSize < reqSize) {
1233 continue;
1234 }
1235
1236 // There could be enough non-contiguous frames available to satisfy the remaining request
1237 if (mRemainingFrames <= nonContig) {
1238 continue;
1239 }
1240
1241 #if 0
1242 // This heuristic tries to collapse a series of EVENT_MORE_DATA that would total to a
1243 // sum <= notificationFrames. It replaces that series by at most two EVENT_MORE_DATA
1244 // that total to a sum == notificationFrames.
1245 if (0 < misalignment && misalignment <= mRemainingFrames) {
1246 mRemainingFrames = misalignment;
1247 return (mRemainingFrames * 1100000000LL) / mSampleRate;
1248 }
1249 #endif
1250
1251 }
1252 if (readFrames > 0) {
1253 AutoMutex lock(mLock);
1254 mFramesRead += readFrames;
1255 // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time.
1256 }
1257 mRemainingFrames = notificationFrames;
1258 mRetryOnPartialBuffer = true;
1259
1260 // A lot has transpired since ns was calculated, so run again immediately and re-calculate
1261 return 0;
1262 }
1263
restoreRecord_l(const char * from)1264 status_t AudioRecord::restoreRecord_l(const char *from)
1265 {
1266 ALOGW("dead IAudioRecord, creating a new one from %s()", from);
1267 ++mSequence;
1268
1269 const int INITIAL_RETRIES = 3;
1270 int retries = INITIAL_RETRIES;
1271 retry:
1272 if (retries < INITIAL_RETRIES) {
1273 // refresh the audio configuration cache in this process to make sure we get new
1274 // input parameters and new IAudioRecord in createRecord_l()
1275 AudioSystem::clearAudioConfigCache();
1276 }
1277 mFlags = mOrigFlags;
1278
1279 // if the new IAudioRecord is created, createRecord_l() will modify the
1280 // following member variables: mAudioRecord, mCblkMemory, mCblk, mBufferMemory.
1281 // It will also delete the strong references on previous IAudioRecord and IMemory
1282 Modulo<uint32_t> position(mProxy->getPosition());
1283 mNewPosition = position + mUpdatePeriod;
1284 status_t result = createRecord_l(position, mOpPackageName);
1285
1286 if (result != NO_ERROR) {
1287 ALOGW("%s(): createRecord_l failed, do not retry", __func__);
1288 retries = 0;
1289 } else {
1290 if (mActive) {
1291 // callback thread or sync event hasn't changed
1292 // FIXME this fails if we have a new AudioFlinger instance
1293 result = mAudioRecord->start(
1294 AudioSystem::SYNC_EVENT_SAME, AUDIO_SESSION_NONE).transactionError();
1295 }
1296 mFramesReadServerOffset = mFramesRead; // server resets to zero so we need an offset.
1297 }
1298
1299 if (result != NO_ERROR) {
1300 ALOGW("%s() failed status %d, retries %d", __func__, result, retries);
1301 if (--retries > 0) {
1302 goto retry;
1303 }
1304 }
1305
1306 if (result != NO_ERROR) {
1307 ALOGW("restoreRecord_l() failed status %d", result);
1308 mActive = false;
1309 }
1310
1311 return result;
1312 }
1313
addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)1314 status_t AudioRecord::addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback)
1315 {
1316 if (callback == 0) {
1317 ALOGW("%s adding NULL callback!", __FUNCTION__);
1318 return BAD_VALUE;
1319 }
1320 AutoMutex lock(mLock);
1321 if (mDeviceCallback.unsafe_get() == callback.get()) {
1322 ALOGW("%s adding same callback!", __FUNCTION__);
1323 return INVALID_OPERATION;
1324 }
1325 status_t status = NO_ERROR;
1326 if (mInput != AUDIO_IO_HANDLE_NONE) {
1327 if (mDeviceCallback != 0) {
1328 ALOGW("%s callback already present!", __FUNCTION__);
1329 AudioSystem::removeAudioDeviceCallback(this, mInput);
1330 }
1331 status = AudioSystem::addAudioDeviceCallback(this, mInput);
1332 }
1333 mDeviceCallback = callback;
1334 return status;
1335 }
1336
removeAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)1337 status_t AudioRecord::removeAudioDeviceCallback(
1338 const sp<AudioSystem::AudioDeviceCallback>& callback)
1339 {
1340 if (callback == 0) {
1341 ALOGW("%s removing NULL callback!", __FUNCTION__);
1342 return BAD_VALUE;
1343 }
1344 AutoMutex lock(mLock);
1345 if (mDeviceCallback.unsafe_get() != callback.get()) {
1346 ALOGW("%s removing different callback!", __FUNCTION__);
1347 return INVALID_OPERATION;
1348 }
1349 mDeviceCallback.clear();
1350 if (mInput != AUDIO_IO_HANDLE_NONE) {
1351 AudioSystem::removeAudioDeviceCallback(this, mInput);
1352 }
1353 return NO_ERROR;
1354 }
1355
onAudioDeviceUpdate(audio_io_handle_t audioIo,audio_port_handle_t deviceId)1356 void AudioRecord::onAudioDeviceUpdate(audio_io_handle_t audioIo,
1357 audio_port_handle_t deviceId)
1358 {
1359 sp<AudioSystem::AudioDeviceCallback> callback;
1360 {
1361 AutoMutex lock(mLock);
1362 if (audioIo != mInput) {
1363 return;
1364 }
1365 callback = mDeviceCallback.promote();
1366 // only update device if the record is active as route changes due to other use cases are
1367 // irrelevant for this client
1368 if (mActive) {
1369 mRoutedDeviceId = deviceId;
1370 }
1371 }
1372 if (callback.get() != nullptr) {
1373 callback->onAudioDeviceUpdate(mInput, mRoutedDeviceId);
1374 }
1375 }
1376
1377 // -------------------------------------------------------------------------
1378
getActiveMicrophones(std::vector<media::MicrophoneInfo> * activeMicrophones)1379 status_t AudioRecord::getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones)
1380 {
1381 AutoMutex lock(mLock);
1382 return mAudioRecord->getActiveMicrophones(activeMicrophones).transactionError();
1383 }
1384
1385 // =========================================================================
1386
binderDied(const wp<IBinder> & who __unused)1387 void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who __unused)
1388 {
1389 sp<AudioRecord> audioRecord = mAudioRecord.promote();
1390 if (audioRecord != 0) {
1391 AutoMutex lock(audioRecord->mLock);
1392 audioRecord->mProxy->binderDied();
1393 }
1394 }
1395
1396 // =========================================================================
1397
AudioRecordThread(AudioRecord & receiver,bool bCanCallJava)1398 AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava)
1399 : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL),
1400 mIgnoreNextPausedInt(false)
1401 {
1402 }
1403
~AudioRecordThread()1404 AudioRecord::AudioRecordThread::~AudioRecordThread()
1405 {
1406 }
1407
threadLoop()1408 bool AudioRecord::AudioRecordThread::threadLoop()
1409 {
1410 {
1411 AutoMutex _l(mMyLock);
1412 if (mPaused) {
1413 // TODO check return value and handle or log
1414 mMyCond.wait(mMyLock);
1415 // caller will check for exitPending()
1416 return true;
1417 }
1418 if (mIgnoreNextPausedInt) {
1419 mIgnoreNextPausedInt = false;
1420 mPausedInt = false;
1421 }
1422 if (mPausedInt) {
1423 if (mPausedNs > 0) {
1424 // TODO check return value and handle or log
1425 (void) mMyCond.waitRelative(mMyLock, mPausedNs);
1426 } else {
1427 // TODO check return value and handle or log
1428 mMyCond.wait(mMyLock);
1429 }
1430 mPausedInt = false;
1431 return true;
1432 }
1433 }
1434 if (exitPending()) {
1435 return false;
1436 }
1437 nsecs_t ns = mReceiver.processAudioBuffer();
1438 switch (ns) {
1439 case 0:
1440 return true;
1441 case NS_INACTIVE:
1442 pauseInternal();
1443 return true;
1444 case NS_NEVER:
1445 return false;
1446 case NS_WHENEVER:
1447 // Event driven: call wake() when callback notifications conditions change.
1448 ns = INT64_MAX;
1449 // fall through
1450 default:
1451 LOG_ALWAYS_FATAL_IF(ns < 0, "processAudioBuffer() returned %" PRId64, ns);
1452 pauseInternal(ns);
1453 return true;
1454 }
1455 }
1456
requestExit()1457 void AudioRecord::AudioRecordThread::requestExit()
1458 {
1459 // must be in this order to avoid a race condition
1460 Thread::requestExit();
1461 resume();
1462 }
1463
pause()1464 void AudioRecord::AudioRecordThread::pause()
1465 {
1466 AutoMutex _l(mMyLock);
1467 mPaused = true;
1468 }
1469
resume()1470 void AudioRecord::AudioRecordThread::resume()
1471 {
1472 AutoMutex _l(mMyLock);
1473 mIgnoreNextPausedInt = true;
1474 if (mPaused || mPausedInt) {
1475 mPaused = false;
1476 mPausedInt = false;
1477 mMyCond.signal();
1478 }
1479 }
1480
wake()1481 void AudioRecord::AudioRecordThread::wake()
1482 {
1483 AutoMutex _l(mMyLock);
1484 if (!mPaused) {
1485 // wake() might be called while servicing a callback - ignore the next
1486 // pause time and call processAudioBuffer.
1487 mIgnoreNextPausedInt = true;
1488 if (mPausedInt && mPausedNs > 0) {
1489 // audio record is active and internally paused with timeout.
1490 mPausedInt = false;
1491 mMyCond.signal();
1492 }
1493 }
1494 }
1495
pauseInternal(nsecs_t ns)1496 void AudioRecord::AudioRecordThread::pauseInternal(nsecs_t ns)
1497 {
1498 AutoMutex _l(mMyLock);
1499 mPausedInt = true;
1500 mPausedNs = ns;
1501 }
1502
1503 // -------------------------------------------------------------------------
1504
1505 } // namespace android
1506