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