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