AudioPolicyService.cpp revision 1b2a794a27caab3a1320d22b872b04ef73e96555
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "AudioPolicyService"
18//#define LOG_NDEBUG 0
19
20#include "Configuration.h"
21#undef __STRICT_ANSI__
22#define __STDINT_LIMITS
23#define __STDC_LIMIT_MACROS
24#include <stdint.h>
25
26#include <sys/time.h>
27#include <binder/IServiceManager.h>
28#include <utils/Log.h>
29#include <cutils/properties.h>
30#include <binder/IPCThreadState.h>
31#include <utils/String16.h>
32#include <utils/threads.h>
33#include "AudioPolicyService.h"
34#include "ServiceUtilities.h"
35#include <hardware_legacy/power.h>
36#include <media/AudioEffect.h>
37#include <media/AudioParameter.h>
38
39#include <system/audio.h>
40#include <system/audio_policy.h>
41
42namespace android {
43
44static const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n";
45static const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n";
46
47static const int kDumpLockRetries = 50;
48static const int kDumpLockSleepUs = 20000;
49
50static const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds
51
52
53// ----------------------------------------------------------------------------
54
55AudioPolicyService::AudioPolicyService()
56    : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
57      mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID)
58{
59}
60
61void AudioPolicyService::onFirstRef()
62{
63    {
64        Mutex::Autolock _l(mLock);
65
66        // start tone playback thread
67        mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
68        // start audio commands thread
69        mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
70        // start output activity command thread
71        mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
72
73        mAudioPolicyClient = new AudioPolicyClient(this);
74        mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
75    }
76    // load audio processing modules
77    sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects();
78    {
79        Mutex::Autolock _l(mLock);
80        mAudioPolicyEffects = audioPolicyEffects;
81    }
82}
83
84AudioPolicyService::~AudioPolicyService()
85{
86    mTonePlaybackThread->exit();
87    mAudioCommandThread->exit();
88    mOutputCommandThread->exit();
89
90    destroyAudioPolicyManager(mAudioPolicyManager);
91    delete mAudioPolicyClient;
92
93    mNotificationClients.clear();
94    mAudioPolicyEffects.clear();
95}
96
97// A notification client is always registered by AudioSystem when the client process
98// connects to AudioPolicyService.
99void AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client)
100{
101    if (client == 0) {
102        ALOGW("%s got NULL client", __FUNCTION__);
103        return;
104    }
105    Mutex::Autolock _l(mNotificationClientsLock);
106
107    uid_t uid = IPCThreadState::self()->getCallingUid();
108    if (mNotificationClients.indexOfKey(uid) < 0) {
109        sp<NotificationClient> notificationClient = new NotificationClient(this,
110                                                                           client,
111                                                                           uid);
112        ALOGV("registerClient() client %p, uid %d", client.get(), uid);
113
114        mNotificationClients.add(uid, notificationClient);
115
116        sp<IBinder> binder = IInterface::asBinder(client);
117        binder->linkToDeath(notificationClient);
118    }
119}
120
121void AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled)
122{
123    Mutex::Autolock _l(mNotificationClientsLock);
124
125    uid_t uid = IPCThreadState::self()->getCallingUid();
126    if (mNotificationClients.indexOfKey(uid) < 0) {
127        return;
128    }
129    mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled);
130}
131
132// removeNotificationClient() is called when the client process dies.
133void AudioPolicyService::removeNotificationClient(uid_t uid)
134{
135    {
136        Mutex::Autolock _l(mNotificationClientsLock);
137        mNotificationClients.removeItem(uid);
138    }
139    {
140        Mutex::Autolock _l(mLock);
141        if (mAudioPolicyManager) {
142            mAudioPolicyManager->releaseResourcesForUid(uid);
143        }
144    }
145}
146
147void AudioPolicyService::onAudioPortListUpdate()
148{
149    mOutputCommandThread->updateAudioPortListCommand();
150}
151
152void AudioPolicyService::doOnAudioPortListUpdate()
153{
154    Mutex::Autolock _l(mNotificationClientsLock);
155    for (size_t i = 0; i < mNotificationClients.size(); i++) {
156        mNotificationClients.valueAt(i)->onAudioPortListUpdate();
157    }
158}
159
160void AudioPolicyService::onAudioPatchListUpdate()
161{
162    mOutputCommandThread->updateAudioPatchListCommand();
163}
164
165void AudioPolicyService::doOnAudioPatchListUpdate()
166{
167    Mutex::Autolock _l(mNotificationClientsLock);
168    for (size_t i = 0; i < mNotificationClients.size(); i++) {
169        mNotificationClients.valueAt(i)->onAudioPatchListUpdate();
170    }
171}
172
173void AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
174{
175    ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)",
176            regId.string(), state);
177    mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state);
178}
179
180void AudioPolicyService::doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
181{
182    Mutex::Autolock _l(mNotificationClientsLock);
183    for (size_t i = 0; i < mNotificationClients.size(); i++) {
184        mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state);
185    }
186}
187
188void AudioPolicyService::onRecordingConfigurationUpdate(int event,
189        const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
190        const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
191{
192    mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo,
193            clientConfig, deviceConfig, patchHandle);
194}
195
196void AudioPolicyService::doOnRecordingConfigurationUpdate(int event,
197        const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
198        const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
199{
200    Mutex::Autolock _l(mNotificationClientsLock);
201    for (size_t i = 0; i < mNotificationClients.size(); i++) {
202        mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo,
203                clientConfig, deviceConfig, patchHandle);
204    }
205}
206
207status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
208                                                audio_patch_handle_t *handle,
209                                                int delayMs)
210{
211    return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs);
212}
213
214status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle,
215                                                 int delayMs)
216{
217    return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs);
218}
219
220status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config,
221                                                      int delayMs)
222{
223    return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs);
224}
225
226AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service,
227                                                     const sp<IAudioPolicyServiceClient>& client,
228                                                     uid_t uid)
229    : mService(service), mUid(uid), mAudioPolicyServiceClient(client),
230      mAudioPortCallbacksEnabled(false)
231{
232}
233
234AudioPolicyService::NotificationClient::~NotificationClient()
235{
236}
237
238void AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused)
239{
240    sp<NotificationClient> keep(this);
241    sp<AudioPolicyService> service = mService.promote();
242    if (service != 0) {
243        service->removeNotificationClient(mUid);
244    }
245}
246
247void AudioPolicyService::NotificationClient::onAudioPortListUpdate()
248{
249    if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
250        mAudioPolicyServiceClient->onAudioPortListUpdate();
251    }
252}
253
254void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
255{
256    if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
257        mAudioPolicyServiceClient->onAudioPatchListUpdate();
258    }
259}
260
261void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
262        const String8& regId, int32_t state)
263{
264    if (mAudioPolicyServiceClient != 0) {
265        mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state);
266    }
267}
268
269void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate(
270        int event, const record_client_info_t *clientInfo,
271        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
272        audio_patch_handle_t patchHandle)
273{
274    if (mAudioPolicyServiceClient != 0) {
275        mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo,
276                clientConfig, deviceConfig, patchHandle);
277    }
278}
279
280void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled)
281{
282    mAudioPortCallbacksEnabled = enabled;
283}
284
285
286void AudioPolicyService::binderDied(const wp<IBinder>& who) {
287    ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
288            IPCThreadState::self()->getCallingPid());
289}
290
291static bool tryLock(Mutex& mutex)
292{
293    bool locked = false;
294    for (int i = 0; i < kDumpLockRetries; ++i) {
295        if (mutex.tryLock() == NO_ERROR) {
296            locked = true;
297            break;
298        }
299        usleep(kDumpLockSleepUs);
300    }
301    return locked;
302}
303
304status_t AudioPolicyService::dumpInternals(int fd)
305{
306    const size_t SIZE = 256;
307    char buffer[SIZE];
308    String8 result;
309
310    snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager);
311    result.append(buffer);
312    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
313    result.append(buffer);
314    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
315    result.append(buffer);
316
317    write(fd, result.string(), result.size());
318    return NO_ERROR;
319}
320
321status_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused)
322{
323    if (!dumpAllowed()) {
324        dumpPermissionDenial(fd);
325    } else {
326        bool locked = tryLock(mLock);
327        if (!locked) {
328            String8 result(kDeadlockedString);
329            write(fd, result.string(), result.size());
330        }
331
332        dumpInternals(fd);
333        if (mAudioCommandThread != 0) {
334            mAudioCommandThread->dump(fd);
335        }
336        if (mTonePlaybackThread != 0) {
337            mTonePlaybackThread->dump(fd);
338        }
339
340        if (mAudioPolicyManager) {
341            mAudioPolicyManager->dump(fd);
342        }
343
344        if (locked) mLock.unlock();
345    }
346    return NO_ERROR;
347}
348
349status_t AudioPolicyService::dumpPermissionDenial(int fd)
350{
351    const size_t SIZE = 256;
352    char buffer[SIZE];
353    String8 result;
354    snprintf(buffer, SIZE, "Permission Denial: "
355            "can't dump AudioPolicyService from pid=%d, uid=%d\n",
356            IPCThreadState::self()->getCallingPid(),
357            IPCThreadState::self()->getCallingUid());
358    result.append(buffer);
359    write(fd, result.string(), result.size());
360    return NO_ERROR;
361}
362
363status_t AudioPolicyService::onTransact(
364        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
365{
366    return BnAudioPolicyService::onTransact(code, data, reply, flags);
367}
368
369
370// -----------  AudioPolicyService::AudioCommandThread implementation ----------
371
372AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
373                                                           const wp<AudioPolicyService>& service)
374    : Thread(false), mName(name), mService(service)
375{
376    mpToneGenerator = NULL;
377}
378
379
380AudioPolicyService::AudioCommandThread::~AudioCommandThread()
381{
382    if (!mAudioCommands.isEmpty()) {
383        release_wake_lock(mName.string());
384    }
385    mAudioCommands.clear();
386    delete mpToneGenerator;
387}
388
389void AudioPolicyService::AudioCommandThread::onFirstRef()
390{
391    run(mName.string(), ANDROID_PRIORITY_AUDIO);
392}
393
394bool AudioPolicyService::AudioCommandThread::threadLoop()
395{
396    nsecs_t waitTime = -1;
397
398    mLock.lock();
399    while (!exitPending())
400    {
401        sp<AudioPolicyService> svc;
402        while (!mAudioCommands.isEmpty() && !exitPending()) {
403            nsecs_t curTime = systemTime();
404            // commands are sorted by increasing time stamp: execute them from index 0 and up
405            if (mAudioCommands[0]->mTime <= curTime) {
406                sp<AudioCommand> command = mAudioCommands[0];
407                mAudioCommands.removeAt(0);
408                mLastCommand = command;
409
410                switch (command->mCommand) {
411                case START_TONE: {
412                    mLock.unlock();
413                    ToneData *data = (ToneData *)command->mParam.get();
414                    ALOGV("AudioCommandThread() processing start tone %d on stream %d",
415                            data->mType, data->mStream);
416                    delete mpToneGenerator;
417                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
418                    mpToneGenerator->startTone(data->mType);
419                    mLock.lock();
420                    }break;
421                case STOP_TONE: {
422                    mLock.unlock();
423                    ALOGV("AudioCommandThread() processing stop tone");
424                    if (mpToneGenerator != NULL) {
425                        mpToneGenerator->stopTone();
426                        delete mpToneGenerator;
427                        mpToneGenerator = NULL;
428                    }
429                    mLock.lock();
430                    }break;
431                case SET_VOLUME: {
432                    VolumeData *data = (VolumeData *)command->mParam.get();
433                    ALOGV("AudioCommandThread() processing set volume stream %d, \
434                            volume %f, output %d", data->mStream, data->mVolume, data->mIO);
435                    command->mStatus = AudioSystem::setStreamVolume(data->mStream,
436                                                                    data->mVolume,
437                                                                    data->mIO);
438                    }break;
439                case SET_PARAMETERS: {
440                    ParametersData *data = (ParametersData *)command->mParam.get();
441                    ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
442                            data->mKeyValuePairs.string(), data->mIO);
443                    command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
444                    }break;
445                case SET_VOICE_VOLUME: {
446                    VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
447                    ALOGV("AudioCommandThread() processing set voice volume volume %f",
448                            data->mVolume);
449                    command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
450                    }break;
451                case STOP_OUTPUT: {
452                    StopOutputData *data = (StopOutputData *)command->mParam.get();
453                    ALOGV("AudioCommandThread() processing stop output %d",
454                            data->mIO);
455                    svc = mService.promote();
456                    if (svc == 0) {
457                        break;
458                    }
459                    mLock.unlock();
460                    svc->doStopOutput(data->mIO, data->mStream, data->mSession);
461                    mLock.lock();
462                    }break;
463                case RELEASE_OUTPUT: {
464                    ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get();
465                    ALOGV("AudioCommandThread() processing release output %d",
466                            data->mIO);
467                    svc = mService.promote();
468                    if (svc == 0) {
469                        break;
470                    }
471                    mLock.unlock();
472                    svc->doReleaseOutput(data->mIO, data->mStream, data->mSession);
473                    mLock.lock();
474                    }break;
475                case CREATE_AUDIO_PATCH: {
476                    CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get();
477                    ALOGV("AudioCommandThread() processing create audio patch");
478                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
479                    if (af == 0) {
480                        command->mStatus = PERMISSION_DENIED;
481                    } else {
482                        command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle);
483                    }
484                    } break;
485                case RELEASE_AUDIO_PATCH: {
486                    ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get();
487                    ALOGV("AudioCommandThread() processing release audio patch");
488                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
489                    if (af == 0) {
490                        command->mStatus = PERMISSION_DENIED;
491                    } else {
492                        command->mStatus = af->releaseAudioPatch(data->mHandle);
493                    }
494                    } break;
495                case UPDATE_AUDIOPORT_LIST: {
496                    ALOGV("AudioCommandThread() processing update audio port list");
497                    svc = mService.promote();
498                    if (svc == 0) {
499                        break;
500                    }
501                    mLock.unlock();
502                    svc->doOnAudioPortListUpdate();
503                    mLock.lock();
504                    }break;
505                case UPDATE_AUDIOPATCH_LIST: {
506                    ALOGV("AudioCommandThread() processing update audio patch list");
507                    svc = mService.promote();
508                    if (svc == 0) {
509                        break;
510                    }
511                    mLock.unlock();
512                    svc->doOnAudioPatchListUpdate();
513                    mLock.lock();
514                    }break;
515                case SET_AUDIOPORT_CONFIG: {
516                    SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get();
517                    ALOGV("AudioCommandThread() processing set port config");
518                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
519                    if (af == 0) {
520                        command->mStatus = PERMISSION_DENIED;
521                    } else {
522                        command->mStatus = af->setAudioPortConfig(&data->mConfig);
523                    }
524                    } break;
525                case DYN_POLICY_MIX_STATE_UPDATE: {
526                    DynPolicyMixStateUpdateData *data =
527                            (DynPolicyMixStateUpdateData *)command->mParam.get();
528                    ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d",
529                            data->mRegId.string(), data->mState);
530                    svc = mService.promote();
531                    if (svc == 0) {
532                        break;
533                    }
534                    mLock.unlock();
535                    svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState);
536                    mLock.lock();
537                    } break;
538                case RECORDING_CONFIGURATION_UPDATE: {
539                    RecordingConfigurationUpdateData *data =
540                            (RecordingConfigurationUpdateData *)command->mParam.get();
541                    ALOGV("AudioCommandThread() processing recording configuration update");
542                    svc = mService.promote();
543                    if (svc == 0) {
544                        break;
545                    }
546                    mLock.unlock();
547                    svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo,
548                            &data->mClientConfig, &data->mDeviceConfig,
549                            data->mPatchHandle);
550                    mLock.lock();
551                    } break;
552                default:
553                    ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
554                }
555                {
556                    Mutex::Autolock _l(command->mLock);
557                    if (command->mWaitStatus) {
558                        command->mWaitStatus = false;
559                        command->mCond.signal();
560                    }
561                }
562                waitTime = -1;
563                // release mLock before releasing strong reference on the service as
564                // AudioPolicyService destructor calls AudioCommandThread::exit() which
565                // acquires mLock.
566                mLock.unlock();
567                svc.clear();
568                mLock.lock();
569            } else {
570                waitTime = mAudioCommands[0]->mTime - curTime;
571                break;
572            }
573        }
574
575        // release delayed commands wake lock if the queue is empty
576        if (mAudioCommands.isEmpty()) {
577            release_wake_lock(mName.string());
578        }
579
580        // At this stage we have either an empty command queue or the first command in the queue
581        // has a finite delay. So unless we are exiting it is safe to wait.
582        if (!exitPending()) {
583            ALOGV("AudioCommandThread() going to sleep");
584            if (waitTime == -1) {
585                mWaitWorkCV.wait(mLock);
586            } else {
587                mWaitWorkCV.waitRelative(mLock, waitTime);
588            }
589        }
590    }
591    // release delayed commands wake lock before quitting
592    if (!mAudioCommands.isEmpty()) {
593        release_wake_lock(mName.string());
594    }
595    mLock.unlock();
596    return false;
597}
598
599status_t AudioPolicyService::AudioCommandThread::dump(int fd)
600{
601    const size_t SIZE = 256;
602    char buffer[SIZE];
603    String8 result;
604
605    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
606    result.append(buffer);
607    write(fd, result.string(), result.size());
608
609    bool locked = tryLock(mLock);
610    if (!locked) {
611        String8 result2(kCmdDeadlockedString);
612        write(fd, result2.string(), result2.size());
613    }
614
615    snprintf(buffer, SIZE, "- Commands:\n");
616    result = String8(buffer);
617    result.append("   Command Time        Wait pParam\n");
618    for (size_t i = 0; i < mAudioCommands.size(); i++) {
619        mAudioCommands[i]->dump(buffer, SIZE);
620        result.append(buffer);
621    }
622    result.append("  Last Command\n");
623    if (mLastCommand != 0) {
624        mLastCommand->dump(buffer, SIZE);
625        result.append(buffer);
626    } else {
627        result.append("     none\n");
628    }
629
630    write(fd, result.string(), result.size());
631
632    if (locked) mLock.unlock();
633
634    return NO_ERROR;
635}
636
637void AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type,
638        audio_stream_type_t stream)
639{
640    sp<AudioCommand> command = new AudioCommand();
641    command->mCommand = START_TONE;
642    sp<ToneData> data = new ToneData();
643    data->mType = type;
644    data->mStream = stream;
645    command->mParam = data;
646    ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
647    sendCommand(command);
648}
649
650void AudioPolicyService::AudioCommandThread::stopToneCommand()
651{
652    sp<AudioCommand> command = new AudioCommand();
653    command->mCommand = STOP_TONE;
654    ALOGV("AudioCommandThread() adding tone stop");
655    sendCommand(command);
656}
657
658status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
659                                                               float volume,
660                                                               audio_io_handle_t output,
661                                                               int delayMs)
662{
663    sp<AudioCommand> command = new AudioCommand();
664    command->mCommand = SET_VOLUME;
665    sp<VolumeData> data = new VolumeData();
666    data->mStream = stream;
667    data->mVolume = volume;
668    data->mIO = output;
669    command->mParam = data;
670    command->mWaitStatus = true;
671    ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
672            stream, volume, output);
673    return sendCommand(command, delayMs);
674}
675
676status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle,
677                                                                   const char *keyValuePairs,
678                                                                   int delayMs)
679{
680    sp<AudioCommand> command = new AudioCommand();
681    command->mCommand = SET_PARAMETERS;
682    sp<ParametersData> data = new ParametersData();
683    data->mIO = ioHandle;
684    data->mKeyValuePairs = String8(keyValuePairs);
685    command->mParam = data;
686    command->mWaitStatus = true;
687    ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
688            keyValuePairs, ioHandle, delayMs);
689    return sendCommand(command, delayMs);
690}
691
692status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
693{
694    sp<AudioCommand> command = new AudioCommand();
695    command->mCommand = SET_VOICE_VOLUME;
696    sp<VoiceVolumeData> data = new VoiceVolumeData();
697    data->mVolume = volume;
698    command->mParam = data;
699    command->mWaitStatus = true;
700    ALOGV("AudioCommandThread() adding set voice volume volume %f", volume);
701    return sendCommand(command, delayMs);
702}
703
704void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output,
705                                                               audio_stream_type_t stream,
706                                                               audio_session_t session)
707{
708    sp<AudioCommand> command = new AudioCommand();
709    command->mCommand = STOP_OUTPUT;
710    sp<StopOutputData> data = new StopOutputData();
711    data->mIO = output;
712    data->mStream = stream;
713    data->mSession = session;
714    command->mParam = data;
715    ALOGV("AudioCommandThread() adding stop output %d", output);
716    sendCommand(command);
717}
718
719void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output,
720                                                                  audio_stream_type_t stream,
721                                                                  audio_session_t session)
722{
723    sp<AudioCommand> command = new AudioCommand();
724    command->mCommand = RELEASE_OUTPUT;
725    sp<ReleaseOutputData> data = new ReleaseOutputData();
726    data->mIO = output;
727    data->mStream = stream;
728    data->mSession = session;
729    command->mParam = data;
730    ALOGV("AudioCommandThread() adding release output %d", output);
731    sendCommand(command);
732}
733
734status_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand(
735                                                const struct audio_patch *patch,
736                                                audio_patch_handle_t *handle,
737                                                int delayMs)
738{
739    status_t status = NO_ERROR;
740
741    sp<AudioCommand> command = new AudioCommand();
742    command->mCommand = CREATE_AUDIO_PATCH;
743    CreateAudioPatchData *data = new CreateAudioPatchData();
744    data->mPatch = *patch;
745    data->mHandle = *handle;
746    command->mParam = data;
747    command->mWaitStatus = true;
748    ALOGV("AudioCommandThread() adding create patch delay %d", delayMs);
749    status = sendCommand(command, delayMs);
750    if (status == NO_ERROR) {
751        *handle = data->mHandle;
752    }
753    return status;
754}
755
756status_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle,
757                                                 int delayMs)
758{
759    sp<AudioCommand> command = new AudioCommand();
760    command->mCommand = RELEASE_AUDIO_PATCH;
761    ReleaseAudioPatchData *data = new ReleaseAudioPatchData();
762    data->mHandle = handle;
763    command->mParam = data;
764    command->mWaitStatus = true;
765    ALOGV("AudioCommandThread() adding release patch delay %d", delayMs);
766    return sendCommand(command, delayMs);
767}
768
769void AudioPolicyService::AudioCommandThread::updateAudioPortListCommand()
770{
771    sp<AudioCommand> command = new AudioCommand();
772    command->mCommand = UPDATE_AUDIOPORT_LIST;
773    ALOGV("AudioCommandThread() adding update audio port list");
774    sendCommand(command);
775}
776
777void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand()
778{
779    sp<AudioCommand>command = new AudioCommand();
780    command->mCommand = UPDATE_AUDIOPATCH_LIST;
781    ALOGV("AudioCommandThread() adding update audio patch list");
782    sendCommand(command);
783}
784
785status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand(
786                                            const struct audio_port_config *config, int delayMs)
787{
788    sp<AudioCommand> command = new AudioCommand();
789    command->mCommand = SET_AUDIOPORT_CONFIG;
790    SetAudioPortConfigData *data = new SetAudioPortConfigData();
791    data->mConfig = *config;
792    command->mParam = data;
793    command->mWaitStatus = true;
794    ALOGV("AudioCommandThread() adding set port config delay %d", delayMs);
795    return sendCommand(command, delayMs);
796}
797
798void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand(
799        const String8& regId, int32_t state)
800{
801    sp<AudioCommand> command = new AudioCommand();
802    command->mCommand = DYN_POLICY_MIX_STATE_UPDATE;
803    DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData();
804    data->mRegId = regId;
805    data->mState = state;
806    command->mParam = data;
807    ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d",
808            regId.string(), state);
809    sendCommand(command);
810}
811
812void AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand(
813        int event, const record_client_info_t *clientInfo,
814        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
815        audio_patch_handle_t patchHandle)
816{
817    sp<AudioCommand>command = new AudioCommand();
818    command->mCommand = RECORDING_CONFIGURATION_UPDATE;
819    RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData();
820    data->mEvent = event;
821    data->mClientInfo = *clientInfo;
822    data->mClientConfig = *clientConfig;
823    data->mDeviceConfig = *deviceConfig;
824    data->mPatchHandle = patchHandle;
825    command->mParam = data;
826    ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u",
827            event, clientInfo->source, clientInfo->uid);
828    sendCommand(command);
829}
830
831status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
832{
833    {
834        Mutex::Autolock _l(mLock);
835        insertCommand_l(command, delayMs);
836        mWaitWorkCV.signal();
837    }
838    Mutex::Autolock _l(command->mLock);
839    while (command->mWaitStatus) {
840        nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs);
841        if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) {
842            command->mStatus = TIMED_OUT;
843            command->mWaitStatus = false;
844        }
845    }
846    return command->mStatus;
847}
848
849// insertCommand_l() must be called with mLock held
850void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs)
851{
852    ssize_t i;  // not size_t because i will count down to -1
853    Vector < sp<AudioCommand> > removedCommands;
854    command->mTime = systemTime() + milliseconds(delayMs);
855
856    // acquire wake lock to make sure delayed commands are processed
857    if (mAudioCommands.isEmpty()) {
858        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
859    }
860
861    // check same pending commands with later time stamps and eliminate them
862    for (i = (ssize_t)mAudioCommands.size()-1; i >= 0; i--) {
863        sp<AudioCommand> command2 = mAudioCommands[i];
864        // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
865        if (command2->mTime <= command->mTime) break;
866
867        // create audio patch or release audio patch commands are equivalent
868        // with regard to filtering
869        if ((command->mCommand == CREATE_AUDIO_PATCH) ||
870                (command->mCommand == RELEASE_AUDIO_PATCH)) {
871            if ((command2->mCommand != CREATE_AUDIO_PATCH) &&
872                    (command2->mCommand != RELEASE_AUDIO_PATCH)) {
873                continue;
874            }
875        } else if (command2->mCommand != command->mCommand) continue;
876
877        switch (command->mCommand) {
878        case SET_PARAMETERS: {
879            ParametersData *data = (ParametersData *)command->mParam.get();
880            ParametersData *data2 = (ParametersData *)command2->mParam.get();
881            if (data->mIO != data2->mIO) break;
882            ALOGV("Comparing parameter command %s to new command %s",
883                    data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
884            AudioParameter param = AudioParameter(data->mKeyValuePairs);
885            AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
886            for (size_t j = 0; j < param.size(); j++) {
887                String8 key;
888                String8 value;
889                param.getAt(j, key, value);
890                for (size_t k = 0; k < param2.size(); k++) {
891                    String8 key2;
892                    String8 value2;
893                    param2.getAt(k, key2, value2);
894                    if (key2 == key) {
895                        param2.remove(key2);
896                        ALOGV("Filtering out parameter %s", key2.string());
897                        break;
898                    }
899                }
900            }
901            // if all keys have been filtered out, remove the command.
902            // otherwise, update the key value pairs
903            if (param2.size() == 0) {
904                removedCommands.add(command2);
905            } else {
906                data2->mKeyValuePairs = param2.toString();
907            }
908            command->mTime = command2->mTime;
909            // force delayMs to non 0 so that code below does not request to wait for
910            // command status as the command is now delayed
911            delayMs = 1;
912        } break;
913
914        case SET_VOLUME: {
915            VolumeData *data = (VolumeData *)command->mParam.get();
916            VolumeData *data2 = (VolumeData *)command2->mParam.get();
917            if (data->mIO != data2->mIO) break;
918            if (data->mStream != data2->mStream) break;
919            ALOGV("Filtering out volume command on output %d for stream %d",
920                    data->mIO, data->mStream);
921            removedCommands.add(command2);
922            command->mTime = command2->mTime;
923            // force delayMs to non 0 so that code below does not request to wait for
924            // command status as the command is now delayed
925            delayMs = 1;
926        } break;
927
928        case SET_VOICE_VOLUME: {
929            VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
930            VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get();
931            ALOGV("Filtering out voice volume command value %f replaced by %f",
932                  data2->mVolume, data->mVolume);
933            removedCommands.add(command2);
934            command->mTime = command2->mTime;
935            // force delayMs to non 0 so that code below does not request to wait for
936            // command status as the command is now delayed
937            delayMs = 1;
938        } break;
939
940        case CREATE_AUDIO_PATCH:
941        case RELEASE_AUDIO_PATCH: {
942            audio_patch_handle_t handle;
943            struct audio_patch patch;
944            if (command->mCommand == CREATE_AUDIO_PATCH) {
945                handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle;
946                patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch;
947            } else {
948                handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle;
949            }
950            audio_patch_handle_t handle2;
951            struct audio_patch patch2;
952            if (command2->mCommand == CREATE_AUDIO_PATCH) {
953                handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle;
954                patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch;
955            } else {
956                handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle;
957                memset(&patch2, 0, sizeof(patch2));
958            }
959            if (handle != handle2) break;
960            /* Filter CREATE_AUDIO_PATCH commands only when they are issued for
961               same output. */
962            if( (command->mCommand == CREATE_AUDIO_PATCH) &&
963                (command2->mCommand == CREATE_AUDIO_PATCH) ) {
964                bool isOutputDiff = false;
965                if (patch.num_sources == patch2.num_sources) {
966                    for (unsigned count = 0; count < patch.num_sources; count++) {
967                        if (patch.sources[count].id != patch2.sources[count].id) {
968                            isOutputDiff = true;
969                            break;
970                        }
971                    }
972                    if (isOutputDiff)
973                       break;
974                }
975            }
976            ALOGV("Filtering out %s audio patch command for handle %d",
977                  (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle);
978            removedCommands.add(command2);
979            command->mTime = command2->mTime;
980            // force delayMs to non 0 so that code below does not request to wait for
981            // command status as the command is now delayed
982            delayMs = 1;
983        } break;
984
985        case DYN_POLICY_MIX_STATE_UPDATE: {
986
987        } break;
988
989        case RECORDING_CONFIGURATION_UPDATE: {
990
991        } break;
992
993        case START_TONE:
994        case STOP_TONE:
995        default:
996            break;
997        }
998    }
999
1000    // remove filtered commands
1001    for (size_t j = 0; j < removedCommands.size(); j++) {
1002        // removed commands always have time stamps greater than current command
1003        for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
1004            if (mAudioCommands[k].get() == removedCommands[j].get()) {
1005                ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
1006                mAudioCommands.removeAt(k);
1007                break;
1008            }
1009        }
1010    }
1011    removedCommands.clear();
1012
1013    // Disable wait for status if delay is not 0.
1014    // Except for create audio patch command because the returned patch handle
1015    // is needed by audio policy manager
1016    if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) {
1017        command->mWaitStatus = false;
1018    }
1019
1020    // insert command at the right place according to its time stamp
1021    ALOGV("inserting command: %d at index %zd, num commands %zu",
1022            command->mCommand, i+1, mAudioCommands.size());
1023    mAudioCommands.insertAt(command, i + 1);
1024}
1025
1026void AudioPolicyService::AudioCommandThread::exit()
1027{
1028    ALOGV("AudioCommandThread::exit");
1029    {
1030        AutoMutex _l(mLock);
1031        requestExit();
1032        mWaitWorkCV.signal();
1033    }
1034    // Note that we can call it from the thread loop if all other references have been released
1035    // but it will safely return WOULD_BLOCK in this case
1036    requestExitAndWait();
1037}
1038
1039void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
1040{
1041    snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
1042            mCommand,
1043            (int)ns2s(mTime),
1044            (int)ns2ms(mTime)%1000,
1045            mWaitStatus,
1046            mParam.get());
1047}
1048
1049/******* helpers for the service_ops callbacks defined below *********/
1050void AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
1051                                       const char *keyValuePairs,
1052                                       int delayMs)
1053{
1054    mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs,
1055                                           delayMs);
1056}
1057
1058int AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
1059                                        float volume,
1060                                        audio_io_handle_t output,
1061                                        int delayMs)
1062{
1063    return (int)mAudioCommandThread->volumeCommand(stream, volume,
1064                                                   output, delayMs);
1065}
1066
1067int AudioPolicyService::startTone(audio_policy_tone_t tone,
1068                                  audio_stream_type_t stream)
1069{
1070    if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) {
1071        ALOGE("startTone: illegal tone requested (%d)", tone);
1072    }
1073    if (stream != AUDIO_STREAM_VOICE_CALL) {
1074        ALOGE("startTone: illegal stream (%d) requested for tone %d", stream,
1075            tone);
1076    }
1077    mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING,
1078                                          AUDIO_STREAM_VOICE_CALL);
1079    return 0;
1080}
1081
1082int AudioPolicyService::stopTone()
1083{
1084    mTonePlaybackThread->stopToneCommand();
1085    return 0;
1086}
1087
1088int AudioPolicyService::setVoiceVolume(float volume, int delayMs)
1089{
1090    return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
1091}
1092
1093extern "C" {
1094audio_module_handle_t aps_load_hw_module(void *service __unused,
1095                                             const char *name);
1096audio_io_handle_t aps_open_output(void *service __unused,
1097                                         audio_devices_t *pDevices,
1098                                         uint32_t *pSamplingRate,
1099                                         audio_format_t *pFormat,
1100                                         audio_channel_mask_t *pChannelMask,
1101                                         uint32_t *pLatencyMs,
1102                                         audio_output_flags_t flags);
1103
1104audio_io_handle_t aps_open_output_on_module(void *service __unused,
1105                                                   audio_module_handle_t module,
1106                                                   audio_devices_t *pDevices,
1107                                                   uint32_t *pSamplingRate,
1108                                                   audio_format_t *pFormat,
1109                                                   audio_channel_mask_t *pChannelMask,
1110                                                   uint32_t *pLatencyMs,
1111                                                   audio_output_flags_t flags,
1112                                                   const audio_offload_info_t *offloadInfo);
1113audio_io_handle_t aps_open_dup_output(void *service __unused,
1114                                                 audio_io_handle_t output1,
1115                                                 audio_io_handle_t output2);
1116int aps_close_output(void *service __unused, audio_io_handle_t output);
1117int aps_suspend_output(void *service __unused, audio_io_handle_t output);
1118int aps_restore_output(void *service __unused, audio_io_handle_t output);
1119audio_io_handle_t aps_open_input(void *service __unused,
1120                                        audio_devices_t *pDevices,
1121                                        uint32_t *pSamplingRate,
1122                                        audio_format_t *pFormat,
1123                                        audio_channel_mask_t *pChannelMask,
1124                                        audio_in_acoustics_t acoustics __unused);
1125audio_io_handle_t aps_open_input_on_module(void *service __unused,
1126                                                  audio_module_handle_t module,
1127                                                  audio_devices_t *pDevices,
1128                                                  uint32_t *pSamplingRate,
1129                                                  audio_format_t *pFormat,
1130                                                  audio_channel_mask_t *pChannelMask);
1131int aps_close_input(void *service __unused, audio_io_handle_t input);
1132int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream);
1133int aps_move_effects(void *service __unused, audio_session_t session,
1134                                audio_io_handle_t src_output,
1135                                audio_io_handle_t dst_output);
1136char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle,
1137                                     const char *keys);
1138void aps_set_parameters(void *service, audio_io_handle_t io_handle,
1139                                   const char *kv_pairs, int delay_ms);
1140int aps_set_stream_volume(void *service, audio_stream_type_t stream,
1141                                     float volume, audio_io_handle_t output,
1142                                     int delay_ms);
1143int aps_start_tone(void *service, audio_policy_tone_t tone,
1144                              audio_stream_type_t stream);
1145int aps_stop_tone(void *service);
1146int aps_set_voice_volume(void *service, float volume, int delay_ms);
1147};
1148
1149} // namespace android
1150