blob: fb2162960b5704555e43bb9b54b8b1f4d051aa0a [file] [log] [blame]
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001/* //device/include/server/AudioFlinger/AudioFlinger.cpp
2**
3** Copyright 2007, 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
19#define LOG_TAG "AudioFlinger"
20//#define LOG_NDEBUG 0
21
22#include <math.h>
23#include <signal.h>
24#include <sys/time.h>
25#include <sys/resource.h>
26
27#include <utils/IServiceManager.h>
28#include <utils/Log.h>
29#include <utils/Parcel.h>
30#include <utils/IPCThreadState.h>
31#include <utils/String16.h>
32#include <utils/threads.h>
33
34#include <media/AudioTrack.h>
35#include <media/AudioRecord.h>
36
37#include <private/media/AudioTrackShared.h>
38
39#include <hardware/AudioHardwareInterface.h>
40
41#include "AudioMixer.h"
42#include "AudioFlinger.h"
43
44namespace android {
45
46static const nsecs_t kStandbyTimeInNsecs = seconds(3);
47static const unsigned long kBufferRecoveryInUsecs = 2000;
48static const unsigned long kMaxBufferRecoveryInUsecs = 20000;
49static const float MAX_GAIN = 4096.0f;
50
51// retry counts for buffer fill timeout
52// 50 * ~20msecs = 1 second
53static const int8_t kMaxTrackRetries = 50;
54static const int8_t kMaxTrackStartupRetries = 50;
55
56#define AUDIOFLINGER_SECURITY_ENABLED 1
57
58// ----------------------------------------------------------------------------
59
60static bool recordingAllowed() {
61#ifndef HAVE_ANDROID_OS
62 return true;
63#endif
64#if AUDIOFLINGER_SECURITY_ENABLED
65 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
66 bool ok = checkCallingPermission(String16("android.permission.RECORD_AUDIO"));
67 if (!ok) LOGE("Request requires android.permission.RECORD_AUDIO");
68 return ok;
69#else
70 if (!checkCallingPermission(String16("android.permission.RECORD_AUDIO")))
71 LOGW("WARNING: Need to add android.permission.RECORD_AUDIO to manifest");
72 return true;
73#endif
74}
75
76static bool settingsAllowed() {
77#ifndef HAVE_ANDROID_OS
78 return true;
79#endif
80#if AUDIOFLINGER_SECURITY_ENABLED
81 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
82 bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
83 if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
84 return ok;
85#else
86 if (!checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")))
87 LOGW("WARNING: Need to add android.permission.MODIFY_AUDIO_SETTINGS to manifest");
88 return true;
89#endif
90}
91
92// ----------------------------------------------------------------------------
93
94AudioFlinger::AudioFlinger()
95 : BnAudioFlinger(), Thread(false),
96 mMasterVolume(0), mMasterMute(true),
97 mAudioMixer(0), mAudioHardware(0), mOutput(0), mAudioRecordThread(0),
98 mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0),
99 mMixBuffer(0), mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0),
100 mStandby(false), mInWrite(false)
101{
102 mHardwareStatus = AUDIO_HW_IDLE;
103 mAudioHardware = AudioHardwareInterface::create();
104 mHardwareStatus = AUDIO_HW_INIT;
105 if (mAudioHardware->initCheck() == NO_ERROR) {
106 // open 16-bit output stream for s/w mixer
107 mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
108 mOutput = mAudioHardware->openOutputStream(AudioSystem::PCM_16_BIT);
109 mHardwareStatus = AUDIO_HW_IDLE;
110 if (mOutput) {
111 mSampleRate = mOutput->sampleRate();
112 mChannelCount = mOutput->channelCount();
113 mFormat = mOutput->format();
114 mMixBufferSize = mOutput->bufferSize();
115 mFrameCount = mMixBufferSize / mChannelCount / sizeof(int16_t);
116 mMixBuffer = new int16_t[mFrameCount * mChannelCount];
117 memset(mMixBuffer, 0, mMixBufferSize);
118 mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
119 // FIXME - this should come from settings
120 setMasterVolume(1.0f);
121 setRouting(AudioSystem::MODE_NORMAL, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
122 setRouting(AudioSystem::MODE_RINGTONE, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
123 setRouting(AudioSystem::MODE_IN_CALL, AudioSystem::ROUTE_EARPIECE, AudioSystem::ROUTE_ALL);
124 setMode(AudioSystem::MODE_NORMAL);
125 mMasterMute = false;
126 } else {
127 LOGE("Failed to initialize output stream");
128 }
129 } else {
130 LOGE("Couldn't even initialize the stubbed audio hardware!");
131 }
132}
133
134AudioFlinger::~AudioFlinger()
135{
136 delete mOutput;
137 delete mAudioHardware;
138 delete [] mMixBuffer;
139 delete mAudioMixer;
140 mAudioRecordThread.clear();
141}
142
143status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
144{
145 const size_t SIZE = 256;
146 char buffer[SIZE];
147 String8 result;
148
149 result.append("Clients:\n");
150 for (size_t i = 0; i < mClients.size(); ++i) {
151 wp<Client> wClient = mClients.valueAt(i);
152 if (wClient != 0) {
153 sp<Client> client = wClient.promote();
154 if (client != 0) {
155 snprintf(buffer, SIZE, " pid: %d\n", client->pid());
156 result.append(buffer);
157 }
158 }
159 }
160 write(fd, result.string(), result.size());
161 return NO_ERROR;
162}
163
164status_t AudioFlinger::dumpTracks(int fd, const Vector<String16>& args)
165{
166 const size_t SIZE = 256;
167 char buffer[SIZE];
168 String8 result;
169
170 result.append("Tracks:\n");
171 result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
172 for (size_t i = 0; i < mTracks.size(); ++i) {
173 wp<Track> wTrack = mTracks[i];
174 if (wTrack != 0) {
175 sp<Track> track = wTrack.promote();
176 if (track != 0) {
177 track->dump(buffer, SIZE);
178 result.append(buffer);
179 }
180 }
181 }
182
183 result.append("Active Tracks:\n");
184 result.append(" Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
185 for (size_t i = 0; i < mActiveTracks.size(); ++i) {
186 wp<Track> wTrack = mTracks[i];
187 if (wTrack != 0) {
188 sp<Track> track = wTrack.promote();
189 if (track != 0) {
190 track->dump(buffer, SIZE);
191 result.append(buffer);
192 }
193 }
194 }
195 write(fd, result.string(), result.size());
196 return NO_ERROR;
197}
198
199status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
200{
201 const size_t SIZE = 256;
202 char buffer[SIZE];
203 String8 result;
204
205 snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", audioMixer().trackNames());
206 result.append(buffer);
207 snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
208 result.append(buffer);
209 snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
210 result.append(buffer);
211 snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
212 result.append(buffer);
213 snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
214 result.append(buffer);
215 snprintf(buffer, SIZE, "standby: %d\n", mStandby);
216 result.append(buffer);
217 snprintf(buffer, SIZE, "Hardware status: %d\n", mHardwareStatus);
218 result.append(buffer);
219 write(fd, result.string(), result.size());
220 return NO_ERROR;
221}
222
223status_t AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
224{
225 const size_t SIZE = 256;
226 char buffer[SIZE];
227 String8 result;
228 snprintf(buffer, SIZE, "Permission Denial: "
229 "can't dump AudioFlinger from pid=%d, uid=%d\n",
230 IPCThreadState::self()->getCallingPid(),
231 IPCThreadState::self()->getCallingUid());
232 result.append(buffer);
233 write(fd, result.string(), result.size());
234 return NO_ERROR;
235}
236
237status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
238{
239 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
240 dumpPermissionDenial(fd, args);
241 } else {
242 AutoMutex lock(&mLock);
243
244 dumpClients(fd, args);
245 dumpTracks(fd, args);
246 dumpInternals(fd, args);
247 if (mAudioHardware) {
248 mAudioHardware->dumpState(fd, args);
249 }
250 }
251 return NO_ERROR;
252}
253
254// Thread virtuals
255bool AudioFlinger::threadLoop()
256{
257 nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 2;
258 unsigned long sleepTime = kBufferRecoveryInUsecs;
259 const size_t mixBufferSize = mFrameCount*mChannelCount*sizeof(int16_t);
260 int16_t* curBuf = mMixBuffer;
261 Vector< sp<Track> > tracksToRemove;
262 size_t enabledTracks;
263 nsecs_t standbyTime = systemTime();
264
265 do {
266 enabledTracks = 0;
267 { // scope for the lock
268 Mutex::Autolock _l(mLock);
269 const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
270
271 // put audio hardware into standby after short delay
272 if UNLIKELY(!activeTracks.size() && systemTime() > standbyTime) {
273 // wait until we have something to do...
274 LOGV("Audio hardware entering standby\n");
275 mHardwareStatus = AUDIO_HW_STANDBY;
276 if (!mStandby) {
277 mAudioHardware->standby();
278 mStandby = true;
279 }
280 mHardwareStatus = AUDIO_HW_IDLE;
281 // we're about to wait, flush the binder command buffer
282 IPCThreadState::self()->flushCommands();
283 mWaitWorkCV.wait(mLock);
284 LOGV("Audio hardware exiting standby\n");
285 standbyTime = systemTime() + kStandbyTimeInNsecs;
286 continue;
287 }
288
289 // find out which tracks need to be processed
290 size_t count = activeTracks.size();
291 for (size_t i=0 ; i<count ; i++) {
292 sp<Track> t = activeTracks[i].promote();
293 if (t == 0) continue;
294
295 Track* const track = t.get();
296 audio_track_cblk_t* cblk = track->cblk();
297 uint32_t u = cblk->user;
298 uint32_t s = cblk->server;
299
300 // The first time a track is added we wait
301 // for all its buffers to be filled before processing it
302 audioMixer().setActiveTrack(track->name());
303 if ((u > s) && (track->isReady(u, s) || track->isStopped()) &&
304 !track->isPaused())
305 {
306 //LOGD("u=%08x, s=%08x [OK]", u, s);
307
308 // compute volume for this track
309 int16_t left, right;
310 if (track->isMuted() || mMasterMute || track->isPausing()) {
311 left = right = 0;
312 if (track->isPausing()) {
313 LOGV("paused(%d)", track->name());
314 track->setPaused();
315 }
316 } else {
317 float typeVolume = mStreamTypes[track->type()].volume;
318 float v = mMasterVolume * typeVolume;
319 float v_clamped = v * cblk->volume[0];
320 if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
321 left = int16_t(v_clamped);
322 v_clamped = v * cblk->volume[1];
323 if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
324 right = int16_t(v_clamped);
325 }
326
327 // XXX: these things DON'T need to be done each time
328 AudioMixer& mixer(audioMixer());
329 mixer.setBufferProvider(track);
330 mixer.enable(AudioMixer::MIXING);
331
332 int param;
333 if ( track->mFillingUpStatus == Track::FS_FILLED) {
334 // no ramp for the first volume setting
335 track->mFillingUpStatus = Track::FS_ACTIVE;
336 if (track->mState == TrackBase::RESUMING) {
337 track->mState = TrackBase::ACTIVE;
338 param = AudioMixer::RAMP_VOLUME;
339 } else {
340 param = AudioMixer::VOLUME;
341 }
342 } else {
343 param = AudioMixer::RAMP_VOLUME;
344 }
345 mixer.setParameter(param, AudioMixer::VOLUME0, left);
346 mixer.setParameter(param, AudioMixer::VOLUME1, right);
347 mixer.setParameter(
348 AudioMixer::TRACK,
349 AudioMixer::FORMAT, track->format());
350 mixer.setParameter(
351 AudioMixer::TRACK,
352 AudioMixer::CHANNEL_COUNT, track->channelCount());
353 mixer.setParameter(
354 AudioMixer::RESAMPLE,
355 AudioMixer::SAMPLE_RATE,
356 int(cblk->sampleRate));
357
358 // reset retry count
359 track->mRetryCount = kMaxTrackRetries;
360 enabledTracks++;
361 } else {
362 //LOGD("u=%08x, s=%08x [NOT READY]", u, s);
363 if (track->isStopped()) {
364 track->mFillingUpStatus = Track::FS_FILLING;
365 track->mFlags = 0;
366 }
367 if (track->isTerminated() || track->isStopped() || track->isPaused()) {
368 // We have consumed all the buffers of this track.
369 // Remove it from the list of active tracks.
370 LOGV("remove(%d) from active list", track->name());
371 tracksToRemove.add(track);
372 } else {
373 // No buffers for this track. Give it a few chances to
374 // fill a buffer, then remove it from active list.
375 if (--(track->mRetryCount) <= 0) {
376 LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
377 tracksToRemove.add(track);
378 }
379 }
380 // LOGV("disable(%d)", track->name());
381 audioMixer().disable(AudioMixer::MIXING);
382 }
383 }
384
385 // remove all the tracks that need to be...
386 count = tracksToRemove.size();
387 if (UNLIKELY(count)) {
388 for (size_t i=0 ; i<count ; i++) {
389 const sp<Track>& track = tracksToRemove[i];
390 mActiveTracks.remove(track);
391 if (track->isTerminated()) {
392 mTracks.remove(track);
393 audioMixer().deleteTrackName(track->mName);
394 }
395 }
396 }
397 }
398
399 if (LIKELY(enabledTracks)) {
400 // mix buffers...
401 audioMixer().process(curBuf);
402
403 // output audio to hardware
404 mLastWriteTime = systemTime();
405 mInWrite = true;
406 mOutput->write(curBuf, mixBufferSize);
407 mNumWrites++;
408 mInWrite = false;
409 mStandby = false;
410 nsecs_t temp = systemTime();
411 standbyTime = temp + kStandbyTimeInNsecs;
412 nsecs_t delta = temp - mLastWriteTime;
413 if (delta > maxPeriod) {
414 LOGW("write blocked for %llu msecs", ns2ms(delta));
415 mNumDelayedWrites++;
416 }
417 sleepTime = kBufferRecoveryInUsecs;
418 } else {
419 // There was nothing to mix this round, which means all
420 // active tracks were late. Sleep a little bit to give
421 // them another chance. If we're too late, the audio
422 // hardware will zero-fill for us.
423 LOGV("no buffers - usleep(%lu)", sleepTime);
424 usleep(sleepTime);
425 if (sleepTime < kMaxBufferRecoveryInUsecs) {
426 sleepTime += kBufferRecoveryInUsecs;
427 }
428 }
429
430 // finally let go of all our tracks, without the lock held
431 // since we can't guarantee the destructors won't acquire that
432 // same lock.
433 tracksToRemove.clear();
434 } while (true);
435
436 return false;
437}
438
439status_t AudioFlinger::readyToRun()
440{
441 if (mSampleRate == 0) {
442 LOGE("No working audio driver found.");
443 return NO_INIT;
444 }
445 LOGI("AudioFlinger's main thread ready to run.");
446 return NO_ERROR;
447}
448
449void AudioFlinger::onFirstRef()
450{
451 run("AudioFlinger", ANDROID_PRIORITY_URGENT_AUDIO);
452}
453
454// IAudioFlinger interface
455sp<IAudioTrack> AudioFlinger::createTrack(
456 pid_t pid,
457 int streamType,
458 uint32_t sampleRate,
459 int format,
460 int channelCount,
461 int bufferCount,
462 uint32_t flags)
463{
464 if (streamType >= AudioTrack::NUM_STREAM_TYPES) {
465 LOGE("invalid stream type");
466 return NULL;
467 }
468
469 if (sampleRate > MAX_SAMPLE_RATE) {
470 LOGE("Sample rate out of range: %d", sampleRate);
471 return NULL;
472 }
473
474 sp<Track> track;
475 sp<TrackHandle> trackHandle;
476 Mutex::Autolock _l(mLock);
477
478 if (mSampleRate == 0) {
479 LOGE("Audio driver not initialized.");
480 return trackHandle;
481 }
482
483 sp<Client> client;
484 wp<Client> wclient = mClients.valueFor(pid);
485
486 if (wclient != NULL) {
487 client = wclient.promote();
488 } else {
489 client = new Client(this, pid);
490 mClients.add(pid, client);
491 }
492
493 // FIXME: Buffer size should be based on sample rate for consistent latency
494 track = new Track(this, client, streamType, sampleRate, format,
495 channelCount, bufferCount, channelCount == 1 ? mMixBufferSize>>1 : mMixBufferSize);
496 mTracks.add(track);
497 trackHandle = new TrackHandle(track);
498 return trackHandle;
499}
500
501uint32_t AudioFlinger::sampleRate() const
502{
503 return mSampleRate;
504}
505
506int AudioFlinger::channelCount() const
507{
508 return mChannelCount;
509}
510
511int AudioFlinger::format() const
512{
513 return mFormat;
514}
515
516size_t AudioFlinger::frameCount() const
517{
518 return mFrameCount;
519}
520
521status_t AudioFlinger::setMasterVolume(float value)
522{
523 // check calling permissions
524 if (!settingsAllowed()) {
525 return PERMISSION_DENIED;
526 }
527
528 // when hw supports master volume, don't scale in sw mixer
529 AutoMutex lock(mHardwareLock);
530 mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
531 if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
532 mMasterVolume = 1.0f;
533 }
534 else {
535 mMasterVolume = value;
536 }
537 mHardwareStatus = AUDIO_HW_IDLE;
538 return NO_ERROR;
539}
540
541status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
542{
543 // check calling permissions
544 if (!settingsAllowed()) {
545 return PERMISSION_DENIED;
546 }
547 if ((mode < AudioSystem::MODE_CURRENT) || (mode >= AudioSystem::NUM_MODES)) {
548 LOGW("Illegal value: setRouting(%d, %u, %u)", mode, routes, mask);
549 return BAD_VALUE;
550 }
551
552 AutoMutex lock(mHardwareLock);
553 mHardwareStatus = AUDIO_HW_GET_ROUTING;
554 uint32_t r;
555 uint32_t err = mAudioHardware->getRouting(mode, &r);
556 if (err == NO_ERROR) {
557 r = (r & ~mask) | (routes & mask);
558 mHardwareStatus = AUDIO_HW_SET_ROUTING;
559 err = mAudioHardware->setRouting(mode, r);
560 }
561 mHardwareStatus = AUDIO_HW_IDLE;
562 return err;
563}
564
565uint32_t AudioFlinger::getRouting(int mode) const
566{
567 uint32_t routes = 0;
568 if ((mode >= AudioSystem::MODE_CURRENT) && (mode < AudioSystem::NUM_MODES)) {
569 mHardwareStatus = AUDIO_HW_GET_ROUTING;
570 mAudioHardware->getRouting(mode, &routes);
571 mHardwareStatus = AUDIO_HW_IDLE;
572 } else {
573 LOGW("Illegal value: getRouting(%d)", mode);
574 }
575 return routes;
576}
577
578status_t AudioFlinger::setMode(int mode)
579{
580 // check calling permissions
581 if (!settingsAllowed()) {
582 return PERMISSION_DENIED;
583 }
584 if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
585 LOGW("Illegal value: setMode(%d)", mode);
586 return BAD_VALUE;
587 }
588
589 AutoMutex lock(mHardwareLock);
590 mHardwareStatus = AUDIO_HW_SET_MODE;
591 status_t ret = mAudioHardware->setMode(mode);
592 mHardwareStatus = AUDIO_HW_IDLE;
593 return ret;
594}
595
596int AudioFlinger::getMode() const
597{
598 int mode = AudioSystem::MODE_INVALID;
599 mHardwareStatus = AUDIO_HW_SET_MODE;
600 mAudioHardware->getMode(&mode);
601 mHardwareStatus = AUDIO_HW_IDLE;
602 return mode;
603}
604
605status_t AudioFlinger::setMicMute(bool state)
606{
607 // check calling permissions
608 if (!settingsAllowed()) {
609 return PERMISSION_DENIED;
610 }
611
612 AutoMutex lock(mHardwareLock);
613 mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
614 status_t ret = mAudioHardware->setMicMute(state);
615 mHardwareStatus = AUDIO_HW_IDLE;
616 return ret;
617}
618
619bool AudioFlinger::getMicMute() const
620{
621 bool state = AudioSystem::MODE_INVALID;
622 mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
623 mAudioHardware->getMicMute(&state);
624 mHardwareStatus = AUDIO_HW_IDLE;
625 return state;
626}
627
628status_t AudioFlinger::setMasterMute(bool muted)
629{
630 // check calling permissions
631 if (!settingsAllowed()) {
632 return PERMISSION_DENIED;
633 }
634
635 mMasterMute = muted;
636 return NO_ERROR;
637}
638
639float AudioFlinger::masterVolume() const
640{
641 return mMasterVolume;
642}
643
644bool AudioFlinger::masterMute() const
645{
646 return mMasterMute;
647}
648
649status_t AudioFlinger::setStreamVolume(int stream, float value)
650{
651 // check calling permissions
652 if (!settingsAllowed()) {
653 return PERMISSION_DENIED;
654 }
655
656 if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) {
657 return BAD_VALUE;
658 }
659
660 mStreamTypes[stream].volume = value;
661 status_t ret = NO_ERROR;
662 if (stream == AudioTrack::VOICE_CALL) {
663 AutoMutex lock(mHardwareLock);
664 mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
665 ret = mAudioHardware->setVoiceVolume(value);
666 mHardwareStatus = AUDIO_HW_IDLE;
667 }
668 return ret;
669}
670
671status_t AudioFlinger::setStreamMute(int stream, bool muted)
672{
673 // check calling permissions
674 if (!settingsAllowed()) {
675 return PERMISSION_DENIED;
676 }
677
678 if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) {
679 return BAD_VALUE;
680 }
681 mStreamTypes[stream].mute = muted;
682 return NO_ERROR;
683}
684
685float AudioFlinger::streamVolume(int stream) const
686{
687 if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) {
688 return 0.0f;
689 }
690 return mStreamTypes[stream].volume;
691}
692
693bool AudioFlinger::streamMute(int stream) const
694{
695 if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) {
696 return true;
697 }
698 return mStreamTypes[stream].mute;
699}
700
701bool AudioFlinger::isMusicActive() const
702{
703 size_t count = mActiveTracks.size();
704 for (size_t i = 0 ; i < count ; ++i) {
705 sp<Track> t = mActiveTracks[i].promote();
706 if (t == 0) continue;
707 Track* const track = t.get();
708 if (t->mStreamType == AudioTrack::MUSIC)
709 return true;
710 }
711 return false;
712}
713
714status_t AudioFlinger::setParameter(const char* key, const char* value)
715{
716 status_t result;
717 AutoMutex lock(mHardwareLock);
718 mHardwareStatus = AUDIO_SET_PARAMETER;
719 result = mAudioHardware->setParameter(key, value);
720 mHardwareStatus = AUDIO_HW_IDLE;
721 return result;
722}
723
724void AudioFlinger::removeClient(pid_t pid)
725{
726 Mutex::Autolock _l(mLock);
727 mClients.removeItem(pid);
728}
729
730status_t AudioFlinger::addTrack(const sp<Track>& track)
731{
732 Mutex::Autolock _l(mLock);
733
734 // here the track could be either new, or restarted
735 // in both cases "unstop" the track
736 if (track->isPaused()) {
737 track->mState = TrackBase::RESUMING;
738 LOGV("PAUSED => RESUMING (%d)", track->name());
739 } else {
740 track->mState = TrackBase::ACTIVE;
741 LOGV("? => ACTIVE (%d)", track->name());
742 }
743 // set retry count for buffer fill
744 track->mRetryCount = kMaxTrackStartupRetries;
745 LOGV("mWaitWorkCV.broadcast");
746 mWaitWorkCV.broadcast();
747
748 if (mActiveTracks.indexOf(track) < 0) {
749 // the track is newly added, make sure it fills up all its
750 // buffers before playing. This is to ensure the client will
751 // effectively get the latency it requested.
752 track->mFillingUpStatus = Track::FS_FILLING;
753 mActiveTracks.add(track);
754 return NO_ERROR;
755 }
756 return ALREADY_EXISTS;
757}
758
759void AudioFlinger::removeTrack(wp<Track> track, int name)
760{
761 Mutex::Autolock _l(mLock);
762 sp<Track> t = track.promote();
763 if (t!=NULL && (t->mState <= TrackBase::STOPPED)) {
764 remove_track_l(track, name);
765 }
766}
767
768void AudioFlinger::remove_track_l(wp<Track> track, int name)
769{
770 sp<Track> t = track.promote();
771 if (t!=NULL) {
772 t->reset();
773 }
774 audioMixer().deleteTrackName(name);
775 mActiveTracks.remove(track);
776 mWaitWorkCV.broadcast();
777}
778
779void AudioFlinger::destroyTrack(const sp<Track>& track)
780{
781 // NOTE: We're acquiring a strong reference on the track before
782 // acquiring the lock, this is to make sure removing it from
783 // mTracks won't cause the destructor to be called while the lock is
784 // held (note that technically, 'track' could be a reference to an item
785 // in mTracks, which is why we need to do this).
786 sp<Track> keep(track);
787 Mutex::Autolock _l(mLock);
788 track->mState = TrackBase::TERMINATED;
789 if (mActiveTracks.indexOf(track) < 0) {
790 LOGV("remove track (%d) and delete from mixer", track->name());
791 mTracks.remove(track);
792 audioMixer().deleteTrackName(keep->name());
793 }
794}
795
796// ----------------------------------------------------------------------------
797
798AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
799 : RefBase(),
800 mAudioFlinger(audioFlinger),
801 mMemoryDealer(new MemoryDealer(1024*1024)),
802 mPid(pid)
803{
804 // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
805}
806
807AudioFlinger::Client::~Client()
808{
809 mAudioFlinger->removeClient(mPid);
810}
811
812const sp<MemoryDealer>& AudioFlinger::Client::heap() const
813{
814 return mMemoryDealer;
815}
816
817// ----------------------------------------------------------------------------
818
819AudioFlinger::TrackBase::TrackBase(
820 const sp<AudioFlinger>& audioFlinger,
821 const sp<Client>& client,
822 int streamType,
823 uint32_t sampleRate,
824 int format,
825 int channelCount,
826 int bufferCount,
827 int bufferSize)
828 : RefBase(),
829 mAudioFlinger(audioFlinger),
830 mClient(client),
831 mStreamType(streamType),
832 mFormat(format),
833 mChannelCount(channelCount),
834 mBufferCount(bufferCount),
835 mFlags(0),
836 mBufferSize(bufferSize),
837 mState(IDLE),
838 mClientTid(-1)
839{
840 mName = audioFlinger->audioMixer().getTrackName();
841 if (mName < 0) {
842 LOGE("no more track names availlable");
843 return;
844 }
845
846 // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
847 size_t size = sizeof(audio_track_cblk_t) + bufferCount * bufferSize;
848 mCblkMemory = client->heap()->allocate(size);
849 if (mCblkMemory != 0) {
850 mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
851 if (mCblk) { // construct the shared structure in-place.
852 new(mCblk) audio_track_cblk_t();
853 // clear all buffers
854 mCblk->size = bufferSize;
855 mCblk->sampleRate = sampleRate;
856 mBuffers = (char*)mCblk + sizeof(audio_track_cblk_t);
857 memset(mBuffers, 0, bufferCount * bufferSize);
858 }
859 } else {
860 LOGE("not enough memory for AudioTrack size=%u", size);
861 client->heap()->dump("AudioTrack");
862 return;
863 }
864}
865
866AudioFlinger::TrackBase::~TrackBase()
867{
868 mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
869 mCblkMemory.clear(); // and free the shared memory
870 mClient.clear();
871}
872
873void AudioFlinger::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
874{
875 buffer->raw = 0;
876 buffer->frameCount = 0;
877 step();
878}
879
880bool AudioFlinger::TrackBase::step() {
881 bool result;
882 audio_track_cblk_t* cblk = this->cblk();
883
884 result = cblk->stepServer(bufferCount());
885 if (!result) {
886 LOGV("stepServer failed acquiring cblk mutex");
887 mFlags |= STEPSERVER_FAILED;
888 }
889 return result;
890}
891
892void AudioFlinger::TrackBase::reset() {
893 audio_track_cblk_t* cblk = this->cblk();
894
895 cblk->user = 0;
896 cblk->server = 0;
897 mFlags = 0;
898}
899
900sp<IMemory> AudioFlinger::TrackBase::getCblk() const
901{
902 return mCblkMemory;
903}
904
905int AudioFlinger::TrackBase::sampleRate() const {
906 return mCblk->sampleRate;
907}
908
909// ----------------------------------------------------------------------------
910
911AudioFlinger::Track::Track(
912 const sp<AudioFlinger>& audioFlinger,
913 const sp<Client>& client,
914 int streamType,
915 uint32_t sampleRate,
916 int format,
917 int channelCount,
918 int bufferCount,
919 int bufferSize)
920 : TrackBase(audioFlinger, client, streamType, sampleRate, format, channelCount, bufferCount, bufferSize)
921{
922 mVolume[0] = 1.0f;
923 mVolume[1] = 1.0f;
924 mMute = false;
925}
926
927AudioFlinger::Track::~Track()
928{
929 wp<Track> weak(this); // never create a strong ref from the dtor
930 mState = TERMINATED;
931 mAudioFlinger->removeTrack(weak, mName);
932}
933
934void AudioFlinger::Track::destroy()
935{
936 mAudioFlinger->destroyTrack(this);
937}
938
939void AudioFlinger::Track::dump(char* buffer, size_t size)
940{
941 snprintf(buffer, size, " %5d %5d %3u %3u %3u %3u %1d %1d %1d %5u %5u %5u %04x %04x\n",
942 mName - AudioMixer::TRACK0,
943 mClient->pid(),
944 mStreamType,
945 mFormat,
946 mChannelCount,
947 mBufferCount,
948 mState,
949 mMute,
950 mFillingUpStatus,
951 mCblk->sampleRate,
952 mCblk->volume[0],
953 mCblk->volume[1],
954 mCblk->server,
955 mCblk->user);
956}
957
958status_t AudioFlinger::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
959{
960 audio_track_cblk_t* cblk = this->cblk();
961 uint32_t u = cblk->user;
962 uint32_t s = cblk->server;
963
964 // Check if last stepServer failed, try to step now
965 if (mFlags & TrackBase::STEPSERVER_FAILED) {
966 if (!step()) goto getNextBuffer_exit;
967 LOGV("stepServer recovered");
968 mFlags &= ~TrackBase::STEPSERVER_FAILED;
969 }
970
971 if (LIKELY(u > s)) {
972 int index = s & audio_track_cblk_t::BUFFER_MASK;
973 buffer->raw = getBuffer(index);
974 buffer->frameCount = mAudioFlinger->frameCount();
975 return NO_ERROR;
976 }
977getNextBuffer_exit:
978 buffer->raw = 0;
979 buffer->frameCount = 0;
980 return NOT_ENOUGH_DATA;
981}
982
983bool AudioFlinger::Track::isReady(uint32_t u, int32_t s) const {
984 if (mFillingUpStatus != FS_FILLING) return true;
985 const uint32_t u_seq = u & audio_track_cblk_t::SEQUENCE_MASK;
986 const uint32_t u_buf = u & audio_track_cblk_t::BUFFER_MASK;
987 const uint32_t s_seq = s & audio_track_cblk_t::SEQUENCE_MASK;
988 const uint32_t s_buf = s & audio_track_cblk_t::BUFFER_MASK;
989 if (u_seq > s_seq && u_buf == s_buf) {
990 mFillingUpStatus = FS_FILLED;
991 return true;
992 }
993 return false;
994}
995
996status_t AudioFlinger::Track::start()
997{
998 LOGV("start(%d)", mName);
999 mAudioFlinger->addTrack(this);
1000 return NO_ERROR;
1001}
1002
1003void AudioFlinger::Track::stop()
1004{
1005 LOGV("stop(%d)", mName);
1006 Mutex::Autolock _l(mAudioFlinger->mLock);
1007 if (mState > STOPPED) {
1008 mState = STOPPED;
1009 // If the track is not active (PAUSED and buffers full), flush buffers
1010 if (mAudioFlinger->mActiveTracks.indexOf(this) < 0) {
1011 reset();
1012 }
1013 LOGV("(> STOPPED) => STOPPED (%d)", mName);
1014 }
1015}
1016
1017void AudioFlinger::Track::pause()
1018{
1019 LOGV("pause(%d)", mName);
1020 Mutex::Autolock _l(mAudioFlinger->mLock);
1021 if (mState == ACTIVE || mState == RESUMING) {
1022 mState = PAUSING;
1023 LOGV("ACTIVE/RESUMING => PAUSING (%d)", mName);
1024 }
1025}
1026
1027void AudioFlinger::Track::flush()
1028{
1029 LOGV("flush(%d)", mName);
1030 Mutex::Autolock _l(mAudioFlinger->mLock);
1031 if (mState != STOPPED && mState != PAUSED && mState != PAUSING) {
1032 return;
1033 }
1034 // No point remaining in PAUSED state after a flush => go to
1035 // STOPPED state
1036 mState = STOPPED;
1037
1038 // NOTE: reset() will reset cblk->user and cblk->server with
1039 // the risk that at the same time, the AudioMixer is trying to read
1040 // data. In this case, getNextBuffer() would return a NULL pointer
1041 // as audio buffer => the AudioMixer code MUST always test that pointer
1042 // returned by getNextBuffer() is not NULL!
1043 reset();
1044}
1045
1046void AudioFlinger::Track::reset()
1047{
1048 TrackBase::reset();
1049 mFillingUpStatus = FS_FILLING;
1050}
1051
1052void AudioFlinger::Track::mute(bool muted)
1053{
1054 mMute = muted;
1055}
1056
1057void AudioFlinger::Track::setVolume(float left, float right)
1058{
1059 mVolume[0] = left;
1060 mVolume[1] = right;
1061}
1062
1063// ----------------------------------------------------------------------------
1064
1065AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::Track>& track)
1066 : BnAudioTrack(),
1067 mTrack(track)
1068{
1069}
1070
1071AudioFlinger::TrackHandle::~TrackHandle() {
1072 // just stop the track on deletion, associated resources
1073 // will be freed from the main thread once all pending buffers have
1074 // been played. Unless it's not in the active track list, in which
1075 // case we free everything now...
1076 mTrack->destroy();
1077}
1078
1079status_t AudioFlinger::TrackHandle::start() {
1080 return mTrack->start();
1081}
1082
1083void AudioFlinger::TrackHandle::stop() {
1084 mTrack->stop();
1085}
1086
1087void AudioFlinger::TrackHandle::flush() {
1088 mTrack->flush();
1089}
1090
1091void AudioFlinger::TrackHandle::mute(bool e) {
1092 mTrack->mute(e);
1093}
1094
1095void AudioFlinger::TrackHandle::pause() {
1096 mTrack->pause();
1097}
1098
1099void AudioFlinger::TrackHandle::setVolume(float left, float right) {
1100 mTrack->setVolume(left, right);
1101}
1102
1103sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
1104 return mTrack->getCblk();
1105}
1106
1107status_t AudioFlinger::TrackHandle::onTransact(
1108 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1109{
1110 return BnAudioTrack::onTransact(code, data, reply, flags);
1111}
1112
1113// ----------------------------------------------------------------------------
1114
1115sp<AudioFlinger::AudioRecordThread> AudioFlinger::audioRecordThread()
1116{
1117 Mutex::Autolock _l(mLock);
1118 return mAudioRecordThread;
1119}
1120
1121void AudioFlinger::endRecord()
1122{
1123 Mutex::Autolock _l(mLock);
1124 mAudioRecordThread.clear();
1125}
1126
1127sp<IAudioRecord> AudioFlinger::openRecord(
1128 pid_t pid,
1129 int streamType,
1130 uint32_t sampleRate,
1131 int format,
1132 int channelCount,
1133 int bufferCount,
1134 uint32_t flags)
1135{
1136 sp<AudioRecordThread> thread;
1137 sp<RecordTrack> recordTrack;
1138 sp<RecordHandle> recordHandle;
1139 sp<Client> client;
1140 wp<Client> wclient;
1141 AudioStreamIn* input = 0;
1142
1143 // check calling permissions
1144 if (!recordingAllowed()) {
1145 goto Exit;
1146 }
1147
1148 if (uint32_t(streamType) >= AudioRecord::NUM_STREAM_TYPES) {
1149 LOGE("invalid stream type");
1150 goto Exit;
1151 }
1152
1153 if (sampleRate > MAX_SAMPLE_RATE) {
1154 LOGE("Sample rate out of range");
1155 goto Exit;
1156 }
1157
1158 if (mSampleRate == 0) {
1159 LOGE("Audio driver not initialized");
1160 goto Exit;
1161 }
1162
1163 // Create audio thread - take mutex to prevent race condition
1164 {
1165 Mutex::Autolock _l(mLock);
1166 if (mAudioRecordThread != 0) {
1167 LOGE("Record channel already open");
1168 goto Exit;
1169 }
1170 thread = new AudioRecordThread(this);
1171 mAudioRecordThread = thread;
1172 }
1173 // It's safe to release the mutex here since the client doesn't get a
1174 // handle until we return from this call
1175
1176 // open driver, initialize h/w
1177 input = mAudioHardware->openInputStream(
1178 AudioSystem::PCM_16_BIT, channelCount, sampleRate);
1179 if (!input) {
1180 LOGE("Error opening input stream");
1181 mAudioRecordThread.clear();
1182 goto Exit;
1183 }
1184
1185 // add client to list
1186 {
1187 Mutex::Autolock _l(mLock);
1188 wclient = mClients.valueFor(pid);
1189 if (wclient != NULL) {
1190 client = wclient.promote();
1191 } else {
1192 client = new Client(this, pid);
1193 mClients.add(pid, client);
1194 }
1195 }
1196
1197 // create new record track and pass to record thread
1198 recordTrack = new RecordTrack(this, client, streamType, sampleRate,
1199 format, channelCount, bufferCount, input->bufferSize());
1200
1201 // spin up record thread
1202 thread->open(recordTrack, input);
1203 thread->run("AudioRecordThread", PRIORITY_URGENT_AUDIO);
1204
1205 // return to handle to client
1206 recordHandle = new RecordHandle(recordTrack);
1207
1208Exit:
1209 return recordHandle;
1210}
1211
1212status_t AudioFlinger::startRecord() {
1213 sp<AudioRecordThread> t = audioRecordThread();
1214 if (t == 0) return NO_INIT;
1215 return t->start();
1216}
1217
1218void AudioFlinger::stopRecord() {
1219 sp<AudioRecordThread> t = audioRecordThread();
1220 if (t != 0) t->stop();
1221}
1222
1223void AudioFlinger::exitRecord()
1224{
1225 sp<AudioRecordThread> t = audioRecordThread();
1226 if (t != 0) t->exit();
1227}
1228
1229// ----------------------------------------------------------------------------
1230
1231AudioFlinger::RecordTrack::RecordTrack(
1232 const sp<AudioFlinger>& audioFlinger,
1233 const sp<Client>& client,
1234 int streamType,
1235 uint32_t sampleRate,
1236 int format,
1237 int channelCount,
1238 int bufferCount,
1239 int bufferSize)
1240 : TrackBase(audioFlinger, client, streamType, sampleRate, format,
1241 channelCount, bufferCount, bufferSize),
1242 mOverflow(false)
1243{
1244}
1245
1246AudioFlinger::RecordTrack::~RecordTrack()
1247{
1248 mAudioFlinger->audioMixer().deleteTrackName(mName);
1249 mAudioFlinger->exitRecord();
1250}
1251
1252status_t AudioFlinger::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
1253{
1254 audio_track_cblk_t* cblk = this->cblk();
1255 const uint32_t u_seq = cblk->user & audio_track_cblk_t::SEQUENCE_MASK;
1256 const uint32_t u_buf = cblk->user & audio_track_cblk_t::BUFFER_MASK;
1257 const uint32_t s_seq = cblk->server & audio_track_cblk_t::SEQUENCE_MASK;
1258 const uint32_t s_buf = cblk->server & audio_track_cblk_t::BUFFER_MASK;
1259
1260 // Check if last stepServer failed, try to step now
1261 if (mFlags & TrackBase::STEPSERVER_FAILED) {
1262 if (!step()) goto getNextBuffer_exit;
1263 LOGV("stepServer recovered");
1264 mFlags &= ~TrackBase::STEPSERVER_FAILED;
1265 }
1266
1267 if (LIKELY(s_seq == u_seq || s_buf != u_buf)) {
1268 buffer->raw = getBuffer(s_buf);
1269 buffer->frameCount = mAudioFlinger->frameCount();
1270 return NO_ERROR;
1271 }
1272
1273getNextBuffer_exit:
1274 buffer->raw = 0;
1275 buffer->frameCount = 0;
1276 return NOT_ENOUGH_DATA;
1277}
1278
1279status_t AudioFlinger::RecordTrack::start()
1280{
1281 return mAudioFlinger->startRecord();
1282}
1283
1284void AudioFlinger::RecordTrack::stop()
1285{
1286 mAudioFlinger->stopRecord();
1287}
1288
1289// ----------------------------------------------------------------------------
1290
1291AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::RecordTrack>& recordTrack)
1292 : BnAudioRecord(),
1293 mRecordTrack(recordTrack)
1294{
1295}
1296
1297AudioFlinger::RecordHandle::~RecordHandle() {}
1298
1299status_t AudioFlinger::RecordHandle::start() {
1300 LOGV("RecordHandle::start()");
1301 return mRecordTrack->start();
1302}
1303
1304void AudioFlinger::RecordHandle::stop() {
1305 LOGV("RecordHandle::stop()");
1306 mRecordTrack->stop();
1307}
1308
1309sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
1310 return mRecordTrack->getCblk();
1311}
1312
1313status_t AudioFlinger::RecordHandle::onTransact(
1314 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1315{
1316 return BnAudioRecord::onTransact(code, data, reply, flags);
1317}
1318
1319// ----------------------------------------------------------------------------
1320
1321AudioFlinger::AudioRecordThread::AudioRecordThread(const sp<AudioFlinger>& audioFlinger) :
1322 mAudioFlinger(audioFlinger),
1323 mRecordTrack(0),
1324 mInput(0),
1325 mActive(false)
1326{
1327}
1328
1329AudioFlinger::AudioRecordThread::~AudioRecordThread()
1330{
1331}
1332
1333bool AudioFlinger::AudioRecordThread::threadLoop()
1334{
1335 LOGV("AudioRecordThread: start record loop");
1336
1337 // start recording
1338 while (!exitPending()) {
1339 if (!mActive) {
1340 mLock.lock();
1341 if (!mActive && !exitPending()) {
1342 LOGV("AudioRecordThread: loop stopping");
1343 mWaitWorkCV.wait(mLock);
1344 LOGV("AudioRecordThread: loop starting");
1345 }
1346 mLock.unlock();
1347 } else {
1348 // promote strong ref so track isn't deleted while we access it
1349 sp<RecordTrack> t = mRecordTrack.promote();
1350
1351 // if we lose the weak reference, client is gone.
1352 if (t == 0) {
1353 LOGV("AudioRecordThread: client deleted track");
1354 break;
1355 }
1356
1357 if (LIKELY(t->getNextBuffer(&mBuffer) == NO_ERROR)) {
1358 if (mInput->read(mBuffer.raw, t->mBufferSize) < 0) {
1359 LOGE("Error reading audio input");
1360 sleep(1);
1361 }
1362 t->releaseBuffer(&mBuffer);
1363 }
1364
1365 // client isn't retrieving buffers fast enough
1366 else {
1367 if (!t->setOverflow())
1368 LOGW("AudioRecordThread: buffer overflow");
1369 }
1370 }
1371 };
1372
1373 // close hardware
1374 close();
1375
1376 // delete this object - no more data references after this call
1377 mAudioFlinger->endRecord();
1378 return false;
1379}
1380
1381status_t AudioFlinger::AudioRecordThread::open(const sp<RecordTrack>& recordTrack, AudioStreamIn *input) {
1382 LOGV("AudioRecordThread::open");
1383 // check for record channel already open
1384 AutoMutex lock(&mLock);
1385 if (mRecordTrack != NULL) {
1386 LOGE("Record channel already open");
1387 return ALREADY_EXISTS;
1388 }
1389 mRecordTrack = recordTrack;
1390 mInput = input;
1391 return NO_ERROR;
1392}
1393
1394status_t AudioFlinger::AudioRecordThread::start()
1395{
1396 LOGV("AudioRecordThread::start");
1397 AutoMutex lock(&mLock);
1398 if (mActive) return -EBUSY;
1399
1400 sp<RecordTrack> t = mRecordTrack.promote();
1401 if (t == 0) return UNKNOWN_ERROR;
1402
1403 // signal thread to start
1404 LOGV("Signal record thread");
1405 mActive = true;
1406 mWaitWorkCV.signal();
1407 return NO_ERROR;
1408}
1409
1410void AudioFlinger::AudioRecordThread::stop() {
1411 LOGV("AudioRecordThread::stop");
1412 AutoMutex lock(&mLock);
1413 if (mActive) {
1414 mActive = false;
1415 mWaitWorkCV.signal();
1416 }
1417}
1418
1419void AudioFlinger::AudioRecordThread::exit()
1420{
1421 LOGV("AudioRecordThread::exit");
1422 AutoMutex lock(&mLock);
1423 requestExit();
1424 mWaitWorkCV.signal();
1425}
1426
1427
1428status_t AudioFlinger::AudioRecordThread::close()
1429{
1430 LOGV("AudioRecordThread::close");
1431 AutoMutex lock(&mLock);
1432 if (!mInput) return NO_INIT;
1433 delete mInput;
1434 mInput = 0;
1435 return NO_ERROR;
1436}
1437
1438status_t AudioFlinger::onTransact(
1439 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1440{
1441 return BnAudioFlinger::onTransact(code, data, reply, flags);
1442}
1443
1444// ----------------------------------------------------------------------------
1445void AudioFlinger::instantiate() {
1446 defaultServiceManager()->addService(
1447 String16("media.audio_flinger"), new AudioFlinger());
1448}
1449
1450}; // namespace android