• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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