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