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/multiuser.h>
30#include <cutils/properties.h>
31#include <binder/IPCThreadState.h>
32#include <binder/ActivityManager.h>
33#include <binder/PermissionController.h>
34#include <binder/IResultReceiver.h>
35#include <utils/String16.h>
36#include <utils/threads.h>
37#include "AudioPolicyService.h"
38#include "ServiceUtilities.h"
39#include <hardware_legacy/power.h>
40#include <media/AudioEffect.h>
41#include <media/AudioParameter.h>
42
43#include <system/audio.h>
44#include <system/audio_policy.h>
45
46#include <private/android_filesystem_config.h>
47
48namespace android {
49
50static const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n";
51static const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n";
52
53static const int kDumpLockRetries = 50;
54static const int kDumpLockSleepUs = 20000;
55
56static const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds
57
58static const String16 sManageAudioPolicyPermission("android.permission.MANAGE_AUDIO_POLICY");
59
60// ----------------------------------------------------------------------------
61
62AudioPolicyService::AudioPolicyService()
63    : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
64      mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID)
65{
66}
67
68void AudioPolicyService::onFirstRef()
69{
70    {
71        Mutex::Autolock _l(mLock);
72
73        // start tone playback thread
74        mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
75        // start audio commands thread
76        mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
77        // start output activity command thread
78        mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
79
80        mAudioPolicyClient = new AudioPolicyClient(this);
81        mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
82    }
83    // load audio processing modules
84    sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects();
85    {
86        Mutex::Autolock _l(mLock);
87        mAudioPolicyEffects = audioPolicyEffects;
88    }
89
90    mUidPolicy = new UidPolicy(this);
91    mUidPolicy->registerSelf();
92}
93
94AudioPolicyService::~AudioPolicyService()
95{
96    mTonePlaybackThread->exit();
97    mAudioCommandThread->exit();
98    mOutputCommandThread->exit();
99
100    destroyAudioPolicyManager(mAudioPolicyManager);
101    delete mAudioPolicyClient;
102
103    mNotificationClients.clear();
104    mAudioPolicyEffects.clear();
105
106    mUidPolicy->unregisterSelf();
107    mUidPolicy.clear();
108}
109
110// A notification client is always registered by AudioSystem when the client process
111// connects to AudioPolicyService.
112void AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client)
113{
114    if (client == 0) {
115        ALOGW("%s got NULL client", __FUNCTION__);
116        return;
117    }
118    Mutex::Autolock _l(mNotificationClientsLock);
119
120    uid_t uid = IPCThreadState::self()->getCallingUid();
121    if (mNotificationClients.indexOfKey(uid) < 0) {
122        sp<NotificationClient> notificationClient = new NotificationClient(this,
123                                                                           client,
124                                                                           uid);
125        ALOGV("registerClient() client %p, uid %d", client.get(), uid);
126
127        mNotificationClients.add(uid, notificationClient);
128
129        sp<IBinder> binder = IInterface::asBinder(client);
130        binder->linkToDeath(notificationClient);
131    }
132}
133
134void AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled)
135{
136    Mutex::Autolock _l(mNotificationClientsLock);
137
138    uid_t uid = IPCThreadState::self()->getCallingUid();
139    if (mNotificationClients.indexOfKey(uid) < 0) {
140        return;
141    }
142    mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled);
143}
144
145// removeNotificationClient() is called when the client process dies.
146void AudioPolicyService::removeNotificationClient(uid_t uid)
147{
148    {
149        Mutex::Autolock _l(mNotificationClientsLock);
150        mNotificationClients.removeItem(uid);
151    }
152    {
153        Mutex::Autolock _l(mLock);
154        if (mAudioPolicyManager) {
155            // called from binder death notification: no need to clear caller identity
156            mAudioPolicyManager->releaseResourcesForUid(uid);
157        }
158    }
159}
160
161void AudioPolicyService::onAudioPortListUpdate()
162{
163    mOutputCommandThread->updateAudioPortListCommand();
164}
165
166void AudioPolicyService::doOnAudioPortListUpdate()
167{
168    Mutex::Autolock _l(mNotificationClientsLock);
169    for (size_t i = 0; i < mNotificationClients.size(); i++) {
170        mNotificationClients.valueAt(i)->onAudioPortListUpdate();
171    }
172}
173
174void AudioPolicyService::onAudioPatchListUpdate()
175{
176    mOutputCommandThread->updateAudioPatchListCommand();
177}
178
179void AudioPolicyService::doOnAudioPatchListUpdate()
180{
181    Mutex::Autolock _l(mNotificationClientsLock);
182    for (size_t i = 0; i < mNotificationClients.size(); i++) {
183        mNotificationClients.valueAt(i)->onAudioPatchListUpdate();
184    }
185}
186
187void AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
188{
189    ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)",
190            regId.string(), state);
191    mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state);
192}
193
194void AudioPolicyService::doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
195{
196    Mutex::Autolock _l(mNotificationClientsLock);
197    for (size_t i = 0; i < mNotificationClients.size(); i++) {
198        mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state);
199    }
200}
201
202void AudioPolicyService::onRecordingConfigurationUpdate(int event,
203        const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
204        const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
205{
206    mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo,
207            clientConfig, deviceConfig, patchHandle);
208}
209
210void AudioPolicyService::doOnRecordingConfigurationUpdate(int event,
211        const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
212        const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
213{
214    Mutex::Autolock _l(mNotificationClientsLock);
215    for (size_t i = 0; i < mNotificationClients.size(); i++) {
216        mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo,
217                clientConfig, deviceConfig, patchHandle);
218    }
219}
220
221status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
222                                                audio_patch_handle_t *handle,
223                                                int delayMs)
224{
225    return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs);
226}
227
228status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle,
229                                                 int delayMs)
230{
231    return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs);
232}
233
234status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config,
235                                                      int delayMs)
236{
237    return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs);
238}
239
240AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service,
241                                                     const sp<IAudioPolicyServiceClient>& client,
242                                                     uid_t uid)
243    : mService(service), mUid(uid), mAudioPolicyServiceClient(client),
244      mAudioPortCallbacksEnabled(false)
245{
246}
247
248AudioPolicyService::NotificationClient::~NotificationClient()
249{
250}
251
252void AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused)
253{
254    sp<NotificationClient> keep(this);
255    sp<AudioPolicyService> service = mService.promote();
256    if (service != 0) {
257        service->removeNotificationClient(mUid);
258    }
259}
260
261void AudioPolicyService::NotificationClient::onAudioPortListUpdate()
262{
263    if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
264        mAudioPolicyServiceClient->onAudioPortListUpdate();
265    }
266}
267
268void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
269{
270    if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
271        mAudioPolicyServiceClient->onAudioPatchListUpdate();
272    }
273}
274
275void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
276        const String8& regId, int32_t state)
277{
278    if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) {
279        mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state);
280    }
281}
282
283void AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate(
284        int event, const record_client_info_t *clientInfo,
285        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
286        audio_patch_handle_t patchHandle)
287{
288    if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) {
289        mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo,
290                clientConfig, deviceConfig, patchHandle);
291    }
292}
293
294void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled)
295{
296    mAudioPortCallbacksEnabled = enabled;
297}
298
299
300void AudioPolicyService::binderDied(const wp<IBinder>& who) {
301    ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
302            IPCThreadState::self()->getCallingPid());
303}
304
305static bool tryLock(Mutex& mutex)
306{
307    bool locked = false;
308    for (int i = 0; i < kDumpLockRetries; ++i) {
309        if (mutex.tryLock() == NO_ERROR) {
310            locked = true;
311            break;
312        }
313        usleep(kDumpLockSleepUs);
314    }
315    return locked;
316}
317
318status_t AudioPolicyService::dumpInternals(int fd)
319{
320    const size_t SIZE = 256;
321    char buffer[SIZE];
322    String8 result;
323
324    snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager);
325    result.append(buffer);
326    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
327    result.append(buffer);
328    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
329    result.append(buffer);
330
331    write(fd, result.string(), result.size());
332    return NO_ERROR;
333}
334
335void AudioPolicyService::setRecordSilenced(uid_t uid, bool silenced)
336{
337    {
338        Mutex::Autolock _l(mLock);
339        if (mAudioPolicyManager) {
340            AutoCallerClear acc;
341            mAudioPolicyManager->setRecordSilenced(uid, silenced);
342        }
343    }
344    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
345    if (af) {
346        af->setRecordSilenced(uid, silenced);
347    }
348}
349
350status_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused)
351{
352    if (!dumpAllowed()) {
353        dumpPermissionDenial(fd);
354    } else {
355        bool locked = tryLock(mLock);
356        if (!locked) {
357            String8 result(kDeadlockedString);
358            write(fd, result.string(), result.size());
359        }
360
361        dumpInternals(fd);
362        if (mAudioCommandThread != 0) {
363            mAudioCommandThread->dump(fd);
364        }
365        if (mTonePlaybackThread != 0) {
366            mTonePlaybackThread->dump(fd);
367        }
368
369        if (mAudioPolicyManager) {
370            mAudioPolicyManager->dump(fd);
371        }
372
373        if (locked) mLock.unlock();
374    }
375    return NO_ERROR;
376}
377
378status_t AudioPolicyService::dumpPermissionDenial(int fd)
379{
380    const size_t SIZE = 256;
381    char buffer[SIZE];
382    String8 result;
383    snprintf(buffer, SIZE, "Permission Denial: "
384            "can't dump AudioPolicyService from pid=%d, uid=%d\n",
385            IPCThreadState::self()->getCallingPid(),
386            IPCThreadState::self()->getCallingUid());
387    result.append(buffer);
388    write(fd, result.string(), result.size());
389    return NO_ERROR;
390}
391
392status_t AudioPolicyService::onTransact(
393        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
394    switch (code) {
395        case SHELL_COMMAND_TRANSACTION: {
396            int in = data.readFileDescriptor();
397            int out = data.readFileDescriptor();
398            int err = data.readFileDescriptor();
399            int argc = data.readInt32();
400            Vector<String16> args;
401            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
402               args.add(data.readString16());
403            }
404            sp<IBinder> unusedCallback;
405            sp<IResultReceiver> resultReceiver;
406            status_t status;
407            if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
408                return status;
409            }
410            if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
411                return status;
412            }
413            status = shellCommand(in, out, err, args);
414            if (resultReceiver != nullptr) {
415                resultReceiver->send(status);
416            }
417            return NO_ERROR;
418        }
419    }
420
421    return BnAudioPolicyService::onTransact(code, data, reply, flags);
422}
423
424// ------------------- Shell command implementation -------------------
425
426// NOTE: This is a remote API - make sure all args are validated
427status_t AudioPolicyService::shellCommand(int in, int out, int err, Vector<String16>& args) {
428    if (!checkCallingPermission(sManageAudioPolicyPermission, nullptr, nullptr)) {
429        return PERMISSION_DENIED;
430    }
431    if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
432        return BAD_VALUE;
433    }
434    if (args.size() == 3 && args[0] == String16("set-uid-state")) {
435        return handleSetUidState(args, err);
436    } else if (args.size() == 2 && args[0] == String16("reset-uid-state")) {
437        return handleResetUidState(args, err);
438    } else if (args.size() == 2 && args[0] == String16("get-uid-state")) {
439        return handleGetUidState(args, out, err);
440    } else if (args.size() == 1 && args[0] == String16("help")) {
441        printHelp(out);
442        return NO_ERROR;
443    }
444    printHelp(err);
445    return BAD_VALUE;
446}
447
448status_t AudioPolicyService::handleSetUidState(Vector<String16>& args, int err) {
449    PermissionController pc;
450    int uid = pc.getPackageUid(args[1], 0);
451    if (uid <= 0) {
452        ALOGE("Unknown package: '%s'", String8(args[1]).string());
453        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
454        return BAD_VALUE;
455    }
456    bool active = false;
457    if (args[2] == String16("active")) {
458        active = true;
459    } else if ((args[2] != String16("idle"))) {
460        ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
461        return BAD_VALUE;
462    }
463    mUidPolicy->addOverrideUid(uid, active);
464    return NO_ERROR;
465}
466
467status_t AudioPolicyService::handleResetUidState(Vector<String16>& args, int err) {
468    PermissionController pc;
469    int uid = pc.getPackageUid(args[1], 0);
470    if (uid < 0) {
471        ALOGE("Unknown package: '%s'", String8(args[1]).string());
472        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
473        return BAD_VALUE;
474    }
475    mUidPolicy->removeOverrideUid(uid);
476    return NO_ERROR;
477}
478
479status_t AudioPolicyService::handleGetUidState(Vector<String16>& args, int out, int err) {
480    PermissionController pc;
481    int uid = pc.getPackageUid(args[1], 0);
482    if (uid < 0) {
483        ALOGE("Unknown package: '%s'", String8(args[1]).string());
484        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
485        return BAD_VALUE;
486    }
487    if (mUidPolicy->isUidActive(uid)) {
488        return dprintf(out, "active\n");
489    } else {
490        return dprintf(out, "idle\n");
491    }
492}
493
494status_t AudioPolicyService::printHelp(int out) {
495    return dprintf(out, "Audio policy service commands:\n"
496        "  get-uid-state <PACKAGE> gets the uid state\n"
497        "  set-uid-state <PACKAGE> <active|idle> overrides the uid state\n"
498        "  reset-uid-state <PACKAGE> clears the uid state override\n"
499        "  help print this message\n");
500}
501
502// -----------  AudioPolicyService::UidPolicy implementation ----------
503
504void AudioPolicyService::UidPolicy::registerSelf() {
505    ActivityManager am;
506    am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
507            | ActivityManager::UID_OBSERVER_IDLE
508            | ActivityManager::UID_OBSERVER_ACTIVE,
509            ActivityManager::PROCESS_STATE_UNKNOWN,
510            String16("audioserver"));
511    status_t res = am.linkToDeath(this);
512    if (!res) {
513        Mutex::Autolock _l(mLock);
514        mObserverRegistered = true;
515    } else {
516        ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res);
517        am.unregisterUidObserver(this);
518    }
519}
520
521void AudioPolicyService::UidPolicy::unregisterSelf() {
522    ActivityManager am;
523    am.unlinkToDeath(this);
524    am.unregisterUidObserver(this);
525    Mutex::Autolock _l(mLock);
526    mObserverRegistered = false;
527}
528
529void AudioPolicyService::UidPolicy::binderDied(__unused const wp<IBinder> &who) {
530    Mutex::Autolock _l(mLock);
531    mCachedUids.clear();
532    mObserverRegistered = false;
533}
534
535bool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) {
536    if (isServiceUid(uid)) return true;
537    bool needToReregister = false;
538    {
539        Mutex::Autolock _l(mLock);
540        needToReregister = !mObserverRegistered;
541    }
542    if (needToReregister) {
543        // Looks like ActivityManager has died previously, attempt to re-register.
544        registerSelf();
545    }
546    {
547        Mutex::Autolock _l(mLock);
548        auto overrideIter = mOverrideUids.find(uid);
549        if (overrideIter != mOverrideUids.end()) {
550            return overrideIter->second;
551        }
552        // In an absense of the ActivityManager, assume everything to be active.
553        if (!mObserverRegistered) return true;
554        auto cacheIter = mCachedUids.find(uid);
555        if (cacheIter != mCachedUids.end()) {
556            return cacheIter->second;
557        }
558    }
559    ActivityManager am;
560    bool active = am.isUidActive(uid, String16("audioserver"));
561    {
562        Mutex::Autolock _l(mLock);
563        mCachedUids.insert(std::pair<uid_t, bool>(uid, active));
564    }
565    return active;
566}
567
568void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) {
569    updateUidCache(uid, true, true);
570}
571
572void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) {
573    updateUidCache(uid, false, false);
574}
575
576void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
577    updateUidCache(uid, false, true);
578}
579
580bool AudioPolicyService::UidPolicy::isServiceUid(uid_t uid) const {
581    return multiuser_get_app_id(uid) < AID_APP_START;
582}
583
584void AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) {
585    sp<AudioPolicyService> service = mService.promote();
586    if (service != nullptr) {
587        service->setRecordSilenced(uid, !active);
588    }
589}
590
591void AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
592    if (isServiceUid(uid)) return;
593    bool wasOverridden = false, wasActive = false;
594    {
595        Mutex::Autolock _l(mLock);
596        updateUidLocked(&mOverrideUids, uid, active, insert, &wasOverridden, &wasActive);
597    }
598    if (!wasOverridden && insert) {
599        notifyService(uid, active);  // Started to override.
600    } else if (wasOverridden && !insert) {
601        notifyService(uid, isUidActive(uid));  // Override ceased, notify with ground truth.
602    } else if (wasActive != active) {
603        notifyService(uid, active);  // Override updated.
604    }
605}
606
607void AudioPolicyService::UidPolicy::updateUidCache(uid_t uid, bool active, bool insert) {
608    if (isServiceUid(uid)) return;
609    bool wasActive = false;
610    {
611        Mutex::Autolock _l(mLock);
612        updateUidLocked(&mCachedUids, uid, active, insert, nullptr, &wasActive);
613        // Do not notify service if currently overridden.
614        if (mOverrideUids.find(uid) != mOverrideUids.end()) return;
615    }
616    bool nowActive = active && insert;
617    if (wasActive != nowActive) notifyService(uid, nowActive);
618}
619
620void AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t, bool> *uids,
621        uid_t uid, bool active, bool insert, bool *wasThere, bool *wasActive) {
622    auto it = uids->find(uid);
623    if (it != uids->end()) {
624        if (wasThere != nullptr) *wasThere = true;
625        if (wasActive != nullptr) *wasActive = it->second;
626        if (insert) {
627            it->second = active;
628        } else {
629            uids->erase(it);
630        }
631    } else if (insert) {
632        uids->insert(std::pair<uid_t, bool>(uid, active));
633    }
634}
635
636// -----------  AudioPolicyService::AudioCommandThread implementation ----------
637
638AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
639                                                           const wp<AudioPolicyService>& service)
640    : Thread(false), mName(name), mService(service)
641{
642    mpToneGenerator = NULL;
643}
644
645
646AudioPolicyService::AudioCommandThread::~AudioCommandThread()
647{
648    if (!mAudioCommands.isEmpty()) {
649        release_wake_lock(mName.string());
650    }
651    mAudioCommands.clear();
652    delete mpToneGenerator;
653}
654
655void AudioPolicyService::AudioCommandThread::onFirstRef()
656{
657    run(mName.string(), ANDROID_PRIORITY_AUDIO);
658}
659
660bool AudioPolicyService::AudioCommandThread::threadLoop()
661{
662    nsecs_t waitTime = -1;
663
664    mLock.lock();
665    while (!exitPending())
666    {
667        sp<AudioPolicyService> svc;
668        while (!mAudioCommands.isEmpty() && !exitPending()) {
669            nsecs_t curTime = systemTime();
670            // commands are sorted by increasing time stamp: execute them from index 0 and up
671            if (mAudioCommands[0]->mTime <= curTime) {
672                sp<AudioCommand> command = mAudioCommands[0];
673                mAudioCommands.removeAt(0);
674                mLastCommand = command;
675
676                switch (command->mCommand) {
677                case START_TONE: {
678                    mLock.unlock();
679                    ToneData *data = (ToneData *)command->mParam.get();
680                    ALOGV("AudioCommandThread() processing start tone %d on stream %d",
681                            data->mType, data->mStream);
682                    delete mpToneGenerator;
683                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
684                    mpToneGenerator->startTone(data->mType);
685                    mLock.lock();
686                    }break;
687                case STOP_TONE: {
688                    mLock.unlock();
689                    ALOGV("AudioCommandThread() processing stop tone");
690                    if (mpToneGenerator != NULL) {
691                        mpToneGenerator->stopTone();
692                        delete mpToneGenerator;
693                        mpToneGenerator = NULL;
694                    }
695                    mLock.lock();
696                    }break;
697                case SET_VOLUME: {
698                    VolumeData *data = (VolumeData *)command->mParam.get();
699                    ALOGV("AudioCommandThread() processing set volume stream %d, \
700                            volume %f, output %d", data->mStream, data->mVolume, data->mIO);
701                    command->mStatus = AudioSystem::setStreamVolume(data->mStream,
702                                                                    data->mVolume,
703                                                                    data->mIO);
704                    }break;
705                case SET_PARAMETERS: {
706                    ParametersData *data = (ParametersData *)command->mParam.get();
707                    ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
708                            data->mKeyValuePairs.string(), data->mIO);
709                    command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
710                    }break;
711                case SET_VOICE_VOLUME: {
712                    VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
713                    ALOGV("AudioCommandThread() processing set voice volume volume %f",
714                            data->mVolume);
715                    command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
716                    }break;
717                case STOP_OUTPUT: {
718                    StopOutputData *data = (StopOutputData *)command->mParam.get();
719                    ALOGV("AudioCommandThread() processing stop output %d",
720                            data->mIO);
721                    svc = mService.promote();
722                    if (svc == 0) {
723                        break;
724                    }
725                    mLock.unlock();
726                    svc->doStopOutput(data->mIO, data->mStream, data->mSession);
727                    mLock.lock();
728                    }break;
729                case RELEASE_OUTPUT: {
730                    ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get();
731                    ALOGV("AudioCommandThread() processing release output %d",
732                            data->mIO);
733                    svc = mService.promote();
734                    if (svc == 0) {
735                        break;
736                    }
737                    mLock.unlock();
738                    svc->doReleaseOutput(data->mIO, data->mStream, data->mSession);
739                    mLock.lock();
740                    }break;
741                case CREATE_AUDIO_PATCH: {
742                    CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get();
743                    ALOGV("AudioCommandThread() processing create audio patch");
744                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
745                    if (af == 0) {
746                        command->mStatus = PERMISSION_DENIED;
747                    } else {
748                        command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle);
749                    }
750                    } break;
751                case RELEASE_AUDIO_PATCH: {
752                    ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get();
753                    ALOGV("AudioCommandThread() processing release audio patch");
754                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
755                    if (af == 0) {
756                        command->mStatus = PERMISSION_DENIED;
757                    } else {
758                        command->mStatus = af->releaseAudioPatch(data->mHandle);
759                    }
760                    } break;
761                case UPDATE_AUDIOPORT_LIST: {
762                    ALOGV("AudioCommandThread() processing update audio port list");
763                    svc = mService.promote();
764                    if (svc == 0) {
765                        break;
766                    }
767                    mLock.unlock();
768                    svc->doOnAudioPortListUpdate();
769                    mLock.lock();
770                    }break;
771                case UPDATE_AUDIOPATCH_LIST: {
772                    ALOGV("AudioCommandThread() processing update audio patch list");
773                    svc = mService.promote();
774                    if (svc == 0) {
775                        break;
776                    }
777                    mLock.unlock();
778                    svc->doOnAudioPatchListUpdate();
779                    mLock.lock();
780                    }break;
781                case SET_AUDIOPORT_CONFIG: {
782                    SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get();
783                    ALOGV("AudioCommandThread() processing set port config");
784                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
785                    if (af == 0) {
786                        command->mStatus = PERMISSION_DENIED;
787                    } else {
788                        command->mStatus = af->setAudioPortConfig(&data->mConfig);
789                    }
790                    } break;
791                case DYN_POLICY_MIX_STATE_UPDATE: {
792                    DynPolicyMixStateUpdateData *data =
793                            (DynPolicyMixStateUpdateData *)command->mParam.get();
794                    ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d",
795                            data->mRegId.string(), data->mState);
796                    svc = mService.promote();
797                    if (svc == 0) {
798                        break;
799                    }
800                    mLock.unlock();
801                    svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState);
802                    mLock.lock();
803                    } break;
804                case RECORDING_CONFIGURATION_UPDATE: {
805                    RecordingConfigurationUpdateData *data =
806                            (RecordingConfigurationUpdateData *)command->mParam.get();
807                    ALOGV("AudioCommandThread() processing recording configuration update");
808                    svc = mService.promote();
809                    if (svc == 0) {
810                        break;
811                    }
812                    mLock.unlock();
813                    svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo,
814                            &data->mClientConfig, &data->mDeviceConfig,
815                            data->mPatchHandle);
816                    mLock.lock();
817                    } break;
818                default:
819                    ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
820                }
821                {
822                    Mutex::Autolock _l(command->mLock);
823                    if (command->mWaitStatus) {
824                        command->mWaitStatus = false;
825                        command->mCond.signal();
826                    }
827                }
828                waitTime = -1;
829                // release mLock before releasing strong reference on the service as
830                // AudioPolicyService destructor calls AudioCommandThread::exit() which
831                // acquires mLock.
832                mLock.unlock();
833                svc.clear();
834                mLock.lock();
835            } else {
836                waitTime = mAudioCommands[0]->mTime - curTime;
837                break;
838            }
839        }
840
841        // release delayed commands wake lock if the queue is empty
842        if (mAudioCommands.isEmpty()) {
843            release_wake_lock(mName.string());
844        }
845
846        // At this stage we have either an empty command queue or the first command in the queue
847        // has a finite delay. So unless we are exiting it is safe to wait.
848        if (!exitPending()) {
849            ALOGV("AudioCommandThread() going to sleep");
850            if (waitTime == -1) {
851                mWaitWorkCV.wait(mLock);
852            } else {
853                mWaitWorkCV.waitRelative(mLock, waitTime);
854            }
855        }
856    }
857    // release delayed commands wake lock before quitting
858    if (!mAudioCommands.isEmpty()) {
859        release_wake_lock(mName.string());
860    }
861    mLock.unlock();
862    return false;
863}
864
865status_t AudioPolicyService::AudioCommandThread::dump(int fd)
866{
867    const size_t SIZE = 256;
868    char buffer[SIZE];
869    String8 result;
870
871    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
872    result.append(buffer);
873    write(fd, result.string(), result.size());
874
875    bool locked = tryLock(mLock);
876    if (!locked) {
877        String8 result2(kCmdDeadlockedString);
878        write(fd, result2.string(), result2.size());
879    }
880
881    snprintf(buffer, SIZE, "- Commands:\n");
882    result = String8(buffer);
883    result.append("   Command Time        Wait pParam\n");
884    for (size_t i = 0; i < mAudioCommands.size(); i++) {
885        mAudioCommands[i]->dump(buffer, SIZE);
886        result.append(buffer);
887    }
888    result.append("  Last Command\n");
889    if (mLastCommand != 0) {
890        mLastCommand->dump(buffer, SIZE);
891        result.append(buffer);
892    } else {
893        result.append("     none\n");
894    }
895
896    write(fd, result.string(), result.size());
897
898    if (locked) mLock.unlock();
899
900    return NO_ERROR;
901}
902
903void AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type,
904        audio_stream_type_t stream)
905{
906    sp<AudioCommand> command = new AudioCommand();
907    command->mCommand = START_TONE;
908    sp<ToneData> data = new ToneData();
909    data->mType = type;
910    data->mStream = stream;
911    command->mParam = data;
912    ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
913    sendCommand(command);
914}
915
916void AudioPolicyService::AudioCommandThread::stopToneCommand()
917{
918    sp<AudioCommand> command = new AudioCommand();
919    command->mCommand = STOP_TONE;
920    ALOGV("AudioCommandThread() adding tone stop");
921    sendCommand(command);
922}
923
924status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
925                                                               float volume,
926                                                               audio_io_handle_t output,
927                                                               int delayMs)
928{
929    sp<AudioCommand> command = new AudioCommand();
930    command->mCommand = SET_VOLUME;
931    sp<VolumeData> data = new VolumeData();
932    data->mStream = stream;
933    data->mVolume = volume;
934    data->mIO = output;
935    command->mParam = data;
936    command->mWaitStatus = true;
937    ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
938            stream, volume, output);
939    return sendCommand(command, delayMs);
940}
941
942status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle,
943                                                                   const char *keyValuePairs,
944                                                                   int delayMs)
945{
946    sp<AudioCommand> command = new AudioCommand();
947    command->mCommand = SET_PARAMETERS;
948    sp<ParametersData> data = new ParametersData();
949    data->mIO = ioHandle;
950    data->mKeyValuePairs = String8(keyValuePairs);
951    command->mParam = data;
952    command->mWaitStatus = true;
953    ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
954            keyValuePairs, ioHandle, delayMs);
955    return sendCommand(command, delayMs);
956}
957
958status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
959{
960    sp<AudioCommand> command = new AudioCommand();
961    command->mCommand = SET_VOICE_VOLUME;
962    sp<VoiceVolumeData> data = new VoiceVolumeData();
963    data->mVolume = volume;
964    command->mParam = data;
965    command->mWaitStatus = true;
966    ALOGV("AudioCommandThread() adding set voice volume volume %f", volume);
967    return sendCommand(command, delayMs);
968}
969
970void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output,
971                                                               audio_stream_type_t stream,
972                                                               audio_session_t session)
973{
974    sp<AudioCommand> command = new AudioCommand();
975    command->mCommand = STOP_OUTPUT;
976    sp<StopOutputData> data = new StopOutputData();
977    data->mIO = output;
978    data->mStream = stream;
979    data->mSession = session;
980    command->mParam = data;
981    ALOGV("AudioCommandThread() adding stop output %d", output);
982    sendCommand(command);
983}
984
985void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output,
986                                                                  audio_stream_type_t stream,
987                                                                  audio_session_t session)
988{
989    sp<AudioCommand> command = new AudioCommand();
990    command->mCommand = RELEASE_OUTPUT;
991    sp<ReleaseOutputData> data = new ReleaseOutputData();
992    data->mIO = output;
993    data->mStream = stream;
994    data->mSession = session;
995    command->mParam = data;
996    ALOGV("AudioCommandThread() adding release output %d", output);
997    sendCommand(command);
998}
999
1000status_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand(
1001                                                const struct audio_patch *patch,
1002                                                audio_patch_handle_t *handle,
1003                                                int delayMs)
1004{
1005    status_t status = NO_ERROR;
1006
1007    sp<AudioCommand> command = new AudioCommand();
1008    command->mCommand = CREATE_AUDIO_PATCH;
1009    CreateAudioPatchData *data = new CreateAudioPatchData();
1010    data->mPatch = *patch;
1011    data->mHandle = *handle;
1012    command->mParam = data;
1013    command->mWaitStatus = true;
1014    ALOGV("AudioCommandThread() adding create patch delay %d", delayMs);
1015    status = sendCommand(command, delayMs);
1016    if (status == NO_ERROR) {
1017        *handle = data->mHandle;
1018    }
1019    return status;
1020}
1021
1022status_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle,
1023                                                 int delayMs)
1024{
1025    sp<AudioCommand> command = new AudioCommand();
1026    command->mCommand = RELEASE_AUDIO_PATCH;
1027    ReleaseAudioPatchData *data = new ReleaseAudioPatchData();
1028    data->mHandle = handle;
1029    command->mParam = data;
1030    command->mWaitStatus = true;
1031    ALOGV("AudioCommandThread() adding release patch delay %d", delayMs);
1032    return sendCommand(command, delayMs);
1033}
1034
1035void AudioPolicyService::AudioCommandThread::updateAudioPortListCommand()
1036{
1037    sp<AudioCommand> command = new AudioCommand();
1038    command->mCommand = UPDATE_AUDIOPORT_LIST;
1039    ALOGV("AudioCommandThread() adding update audio port list");
1040    sendCommand(command);
1041}
1042
1043void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand()
1044{
1045    sp<AudioCommand>command = new AudioCommand();
1046    command->mCommand = UPDATE_AUDIOPATCH_LIST;
1047    ALOGV("AudioCommandThread() adding update audio patch list");
1048    sendCommand(command);
1049}
1050
1051status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand(
1052                                            const struct audio_port_config *config, int delayMs)
1053{
1054    sp<AudioCommand> command = new AudioCommand();
1055    command->mCommand = SET_AUDIOPORT_CONFIG;
1056    SetAudioPortConfigData *data = new SetAudioPortConfigData();
1057    data->mConfig = *config;
1058    command->mParam = data;
1059    command->mWaitStatus = true;
1060    ALOGV("AudioCommandThread() adding set port config delay %d", delayMs);
1061    return sendCommand(command, delayMs);
1062}
1063
1064void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand(
1065        const String8& regId, int32_t state)
1066{
1067    sp<AudioCommand> command = new AudioCommand();
1068    command->mCommand = DYN_POLICY_MIX_STATE_UPDATE;
1069    DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData();
1070    data->mRegId = regId;
1071    data->mState = state;
1072    command->mParam = data;
1073    ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d",
1074            regId.string(), state);
1075    sendCommand(command);
1076}
1077
1078void AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand(
1079        int event, const record_client_info_t *clientInfo,
1080        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
1081        audio_patch_handle_t patchHandle)
1082{
1083    sp<AudioCommand>command = new AudioCommand();
1084    command->mCommand = RECORDING_CONFIGURATION_UPDATE;
1085    RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData();
1086    data->mEvent = event;
1087    data->mClientInfo = *clientInfo;
1088    data->mClientConfig = *clientConfig;
1089    data->mDeviceConfig = *deviceConfig;
1090    data->mPatchHandle = patchHandle;
1091    command->mParam = data;
1092    ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u",
1093            event, clientInfo->source, clientInfo->uid);
1094    sendCommand(command);
1095}
1096
1097status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
1098{
1099    {
1100        Mutex::Autolock _l(mLock);
1101        insertCommand_l(command, delayMs);
1102        mWaitWorkCV.signal();
1103    }
1104    Mutex::Autolock _l(command->mLock);
1105    while (command->mWaitStatus) {
1106        nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs);
1107        if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) {
1108            command->mStatus = TIMED_OUT;
1109            command->mWaitStatus = false;
1110        }
1111    }
1112    return command->mStatus;
1113}
1114
1115// insertCommand_l() must be called with mLock held
1116void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs)
1117{
1118    ssize_t i;  // not size_t because i will count down to -1
1119    Vector < sp<AudioCommand> > removedCommands;
1120    command->mTime = systemTime() + milliseconds(delayMs);
1121
1122    // acquire wake lock to make sure delayed commands are processed
1123    if (mAudioCommands.isEmpty()) {
1124        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
1125    }
1126
1127    // check same pending commands with later time stamps and eliminate them
1128    for (i = (ssize_t)mAudioCommands.size()-1; i >= 0; i--) {
1129        sp<AudioCommand> command2 = mAudioCommands[i];
1130        // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
1131        if (command2->mTime <= command->mTime) break;
1132
1133        // create audio patch or release audio patch commands are equivalent
1134        // with regard to filtering
1135        if ((command->mCommand == CREATE_AUDIO_PATCH) ||
1136                (command->mCommand == RELEASE_AUDIO_PATCH)) {
1137            if ((command2->mCommand != CREATE_AUDIO_PATCH) &&
1138                    (command2->mCommand != RELEASE_AUDIO_PATCH)) {
1139                continue;
1140            }
1141        } else if (command2->mCommand != command->mCommand) continue;
1142
1143        switch (command->mCommand) {
1144        case SET_PARAMETERS: {
1145            ParametersData *data = (ParametersData *)command->mParam.get();
1146            ParametersData *data2 = (ParametersData *)command2->mParam.get();
1147            if (data->mIO != data2->mIO) break;
1148            ALOGV("Comparing parameter command %s to new command %s",
1149                    data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
1150            AudioParameter param = AudioParameter(data->mKeyValuePairs);
1151            AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
1152            for (size_t j = 0; j < param.size(); j++) {
1153                String8 key;
1154                String8 value;
1155                param.getAt(j, key, value);
1156                for (size_t k = 0; k < param2.size(); k++) {
1157                    String8 key2;
1158                    String8 value2;
1159                    param2.getAt(k, key2, value2);
1160                    if (key2 == key) {
1161                        param2.remove(key2);
1162                        ALOGV("Filtering out parameter %s", key2.string());
1163                        break;
1164                    }
1165                }
1166            }
1167            // if all keys have been filtered out, remove the command.
1168            // otherwise, update the key value pairs
1169            if (param2.size() == 0) {
1170                removedCommands.add(command2);
1171            } else {
1172                data2->mKeyValuePairs = param2.toString();
1173            }
1174            command->mTime = command2->mTime;
1175            // force delayMs to non 0 so that code below does not request to wait for
1176            // command status as the command is now delayed
1177            delayMs = 1;
1178        } break;
1179
1180        case SET_VOLUME: {
1181            VolumeData *data = (VolumeData *)command->mParam.get();
1182            VolumeData *data2 = (VolumeData *)command2->mParam.get();
1183            if (data->mIO != data2->mIO) break;
1184            if (data->mStream != data2->mStream) break;
1185            ALOGV("Filtering out volume command on output %d for stream %d",
1186                    data->mIO, data->mStream);
1187            removedCommands.add(command2);
1188            command->mTime = command2->mTime;
1189            // force delayMs to non 0 so that code below does not request to wait for
1190            // command status as the command is now delayed
1191            delayMs = 1;
1192        } break;
1193
1194        case SET_VOICE_VOLUME: {
1195            VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
1196            VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get();
1197            ALOGV("Filtering out voice volume command value %f replaced by %f",
1198                  data2->mVolume, data->mVolume);
1199            removedCommands.add(command2);
1200            command->mTime = command2->mTime;
1201            // force delayMs to non 0 so that code below does not request to wait for
1202            // command status as the command is now delayed
1203            delayMs = 1;
1204        } break;
1205
1206        case CREATE_AUDIO_PATCH:
1207        case RELEASE_AUDIO_PATCH: {
1208            audio_patch_handle_t handle;
1209            struct audio_patch patch;
1210            if (command->mCommand == CREATE_AUDIO_PATCH) {
1211                handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle;
1212                patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch;
1213            } else {
1214                handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle;
1215            }
1216            audio_patch_handle_t handle2;
1217            struct audio_patch patch2;
1218            if (command2->mCommand == CREATE_AUDIO_PATCH) {
1219                handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle;
1220                patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch;
1221            } else {
1222                handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle;
1223                memset(&patch2, 0, sizeof(patch2));
1224            }
1225            if (handle != handle2) break;
1226            /* Filter CREATE_AUDIO_PATCH commands only when they are issued for
1227               same output. */
1228            if( (command->mCommand == CREATE_AUDIO_PATCH) &&
1229                (command2->mCommand == CREATE_AUDIO_PATCH) ) {
1230                bool isOutputDiff = false;
1231                if (patch.num_sources == patch2.num_sources) {
1232                    for (unsigned count = 0; count < patch.num_sources; count++) {
1233                        if (patch.sources[count].id != patch2.sources[count].id) {
1234                            isOutputDiff = true;
1235                            break;
1236                        }
1237                    }
1238                    if (isOutputDiff)
1239                       break;
1240                }
1241            }
1242            ALOGV("Filtering out %s audio patch command for handle %d",
1243                  (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle);
1244            removedCommands.add(command2);
1245            command->mTime = command2->mTime;
1246            // force delayMs to non 0 so that code below does not request to wait for
1247            // command status as the command is now delayed
1248            delayMs = 1;
1249        } break;
1250
1251        case DYN_POLICY_MIX_STATE_UPDATE: {
1252
1253        } break;
1254
1255        case RECORDING_CONFIGURATION_UPDATE: {
1256
1257        } break;
1258
1259        case START_TONE:
1260        case STOP_TONE:
1261        default:
1262            break;
1263        }
1264    }
1265
1266    // remove filtered commands
1267    for (size_t j = 0; j < removedCommands.size(); j++) {
1268        // removed commands always have time stamps greater than current command
1269        for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
1270            if (mAudioCommands[k].get() == removedCommands[j].get()) {
1271                ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
1272                mAudioCommands.removeAt(k);
1273                break;
1274            }
1275        }
1276    }
1277    removedCommands.clear();
1278
1279    // Disable wait for status if delay is not 0.
1280    // Except for create audio patch command because the returned patch handle
1281    // is needed by audio policy manager
1282    if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) {
1283        command->mWaitStatus = false;
1284    }
1285
1286    // insert command at the right place according to its time stamp
1287    ALOGV("inserting command: %d at index %zd, num commands %zu",
1288            command->mCommand, i+1, mAudioCommands.size());
1289    mAudioCommands.insertAt(command, i + 1);
1290}
1291
1292void AudioPolicyService::AudioCommandThread::exit()
1293{
1294    ALOGV("AudioCommandThread::exit");
1295    {
1296        AutoMutex _l(mLock);
1297        requestExit();
1298        mWaitWorkCV.signal();
1299    }
1300    // Note that we can call it from the thread loop if all other references have been released
1301    // but it will safely return WOULD_BLOCK in this case
1302    requestExitAndWait();
1303}
1304
1305void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
1306{
1307    snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
1308            mCommand,
1309            (int)ns2s(mTime),
1310            (int)ns2ms(mTime)%1000,
1311            mWaitStatus,
1312            mParam.get());
1313}
1314
1315/******* helpers for the service_ops callbacks defined below *********/
1316void AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
1317                                       const char *keyValuePairs,
1318                                       int delayMs)
1319{
1320    mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs,
1321                                           delayMs);
1322}
1323
1324int AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
1325                                        float volume,
1326                                        audio_io_handle_t output,
1327                                        int delayMs)
1328{
1329    return (int)mAudioCommandThread->volumeCommand(stream, volume,
1330                                                   output, delayMs);
1331}
1332
1333int AudioPolicyService::startTone(audio_policy_tone_t tone,
1334                                  audio_stream_type_t stream)
1335{
1336    if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) {
1337        ALOGE("startTone: illegal tone requested (%d)", tone);
1338    }
1339    if (stream != AUDIO_STREAM_VOICE_CALL) {
1340        ALOGE("startTone: illegal stream (%d) requested for tone %d", stream,
1341            tone);
1342    }
1343    mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING,
1344                                          AUDIO_STREAM_VOICE_CALL);
1345    return 0;
1346}
1347
1348int AudioPolicyService::stopTone()
1349{
1350    mTonePlaybackThread->stopToneCommand();
1351    return 0;
1352}
1353
1354int AudioPolicyService::setVoiceVolume(float volume, int delayMs)
1355{
1356    return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
1357}
1358
1359extern "C" {
1360audio_module_handle_t aps_load_hw_module(void *service __unused,
1361                                             const char *name);
1362audio_io_handle_t aps_open_output(void *service __unused,
1363                                         audio_devices_t *pDevices,
1364                                         uint32_t *pSamplingRate,
1365                                         audio_format_t *pFormat,
1366                                         audio_channel_mask_t *pChannelMask,
1367                                         uint32_t *pLatencyMs,
1368                                         audio_output_flags_t flags);
1369
1370audio_io_handle_t aps_open_output_on_module(void *service __unused,
1371                                                   audio_module_handle_t module,
1372                                                   audio_devices_t *pDevices,
1373                                                   uint32_t *pSamplingRate,
1374                                                   audio_format_t *pFormat,
1375                                                   audio_channel_mask_t *pChannelMask,
1376                                                   uint32_t *pLatencyMs,
1377                                                   audio_output_flags_t flags,
1378                                                   const audio_offload_info_t *offloadInfo);
1379audio_io_handle_t aps_open_dup_output(void *service __unused,
1380                                                 audio_io_handle_t output1,
1381                                                 audio_io_handle_t output2);
1382int aps_close_output(void *service __unused, audio_io_handle_t output);
1383int aps_suspend_output(void *service __unused, audio_io_handle_t output);
1384int aps_restore_output(void *service __unused, audio_io_handle_t output);
1385audio_io_handle_t aps_open_input(void *service __unused,
1386                                        audio_devices_t *pDevices,
1387                                        uint32_t *pSamplingRate,
1388                                        audio_format_t *pFormat,
1389                                        audio_channel_mask_t *pChannelMask,
1390                                        audio_in_acoustics_t acoustics __unused);
1391audio_io_handle_t aps_open_input_on_module(void *service __unused,
1392                                                  audio_module_handle_t module,
1393                                                  audio_devices_t *pDevices,
1394                                                  uint32_t *pSamplingRate,
1395                                                  audio_format_t *pFormat,
1396                                                  audio_channel_mask_t *pChannelMask);
1397int aps_close_input(void *service __unused, audio_io_handle_t input);
1398int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream);
1399int aps_move_effects(void *service __unused, audio_session_t session,
1400                                audio_io_handle_t src_output,
1401                                audio_io_handle_t dst_output);
1402char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle,
1403                                     const char *keys);
1404void aps_set_parameters(void *service, audio_io_handle_t io_handle,
1405                                   const char *kv_pairs, int delay_ms);
1406int aps_set_stream_volume(void *service, audio_stream_type_t stream,
1407                                     float volume, audio_io_handle_t output,
1408                                     int delay_ms);
1409int aps_start_tone(void *service, audio_policy_tone_t tone,
1410                              audio_stream_type_t stream);
1411int aps_stop_tone(void *service);
1412int aps_set_voice_volume(void *service, float volume, int delay_ms);
1413};
1414
1415} // namespace android
1416