AudioPolicyService.cpp revision 22ecc912a87099cff8cadc424cd12f85c118673f
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#undef __STRICT_ANSI__
21#define __STDINT_LIMITS
22#define __STDC_LIMIT_MACROS
23#include <stdint.h>
24
25#include <sys/time.h>
26#include <binder/IServiceManager.h>
27#include <utils/Log.h>
28#include <cutils/properties.h>
29#include <binder/IPCThreadState.h>
30#include <utils/String16.h>
31#include <utils/threads.h>
32#include "AudioPolicyService.h"
33#include <cutils/properties.h>
34#include <hardware_legacy/power.h>
35#include <media/AudioEffect.h>
36#include <media/EffectsFactoryApi.h>
37
38#include <hardware/hardware.h>
39#include <system/audio.h>
40#include <system/audio_policy.h>
41#include <hardware/audio_policy.h>
42#include <audio_effects/audio_effects_conf.h>
43
44namespace android {
45
46static const char *kDeadlockedString = "AudioPolicyService may be deadlocked\n";
47static const char *kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n";
48
49static const int kDumpLockRetries = 50;
50static const int kDumpLockSleepUs = 20000;
51
52static bool checkPermission() {
53    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
54    bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
55    if (!ok) ALOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
56    return ok;
57}
58
59namespace {
60    extern struct audio_policy_service_ops aps_ops;
61};
62
63// ----------------------------------------------------------------------------
64
65AudioPolicyService::AudioPolicyService()
66    : BnAudioPolicyService() , mpAudioPolicyDev(NULL) , mpAudioPolicy(NULL)
67{
68    char value[PROPERTY_VALUE_MAX];
69    const struct hw_module_t *module;
70    int forced_val;
71    int rc;
72
73    Mutex::Autolock _l(mLock);
74
75    // start tone playback thread
76    mTonePlaybackThread = new AudioCommandThread(String8(""));
77    // start audio commands thread
78    mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread"));
79
80    /* instantiate the audio policy manager */
81    rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
82    if (rc)
83        return;
84
85    rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
86    ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
87    if (rc)
88        return;
89
90    rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
91                                               &mpAudioPolicy);
92    ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));
93    if (rc)
94        return;
95
96    rc = mpAudioPolicy->init_check(mpAudioPolicy);
97    ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc));
98    if (rc)
99        return;
100
101    property_get("ro.camera.sound.forced", value, "0");
102    forced_val = strtol(value, NULL, 0);
103    mpAudioPolicy->set_can_mute_enforced_audible(mpAudioPolicy, !forced_val);
104
105    ALOGI("Loaded audio policy from %s (%s)", module->name, module->id);
106
107    // load audio pre processing modules
108    if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
109        loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
110    } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
111        loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
112    }
113}
114
115AudioPolicyService::~AudioPolicyService()
116{
117    mTonePlaybackThread->exit();
118    mTonePlaybackThread.clear();
119    mAudioCommandThread->exit();
120    mAudioCommandThread.clear();
121
122
123    // release audio pre processing resources
124    for (size_t i = 0; i < mInputSources.size(); i++) {
125        InputSourceDesc *source = mInputSources.valueAt(i);
126        Vector <EffectDesc *> effects = source->mEffects;
127        for (size_t j = 0; j < effects.size(); j++) {
128            delete effects[j]->mName;
129            Vector <effect_param_t *> params = effects[j]->mParams;
130            for (size_t k = 0; k < params.size(); k++) {
131                delete params[k];
132            }
133            params.clear();
134            delete effects[j];
135        }
136        effects.clear();
137        delete source;
138    }
139    mInputSources.clear();
140
141    for (size_t i = 0; i < mInputs.size(); i++) {
142        mInputs.valueAt(i)->mEffects.clear();
143        delete mInputs.valueAt(i);
144    }
145    mInputs.clear();
146
147    if (mpAudioPolicy && mpAudioPolicyDev)
148        mpAudioPolicyDev->destroy_audio_policy(mpAudioPolicyDev, mpAudioPolicy);
149    if (mpAudioPolicyDev)
150        audio_policy_dev_close(mpAudioPolicyDev);
151}
152
153status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
154                                                  audio_policy_dev_state_t state,
155                                                  const char *device_address)
156{
157    if (mpAudioPolicy == NULL) {
158        return NO_INIT;
159    }
160    if (!checkPermission()) {
161        return PERMISSION_DENIED;
162    }
163    if (!audio_is_output_device(device) && !audio_is_input_device(device)) {
164        return BAD_VALUE;
165    }
166    if (state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE &&
167            state != AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
168        return BAD_VALUE;
169    }
170
171    ALOGV("setDeviceConnectionState() tid %d", gettid());
172    Mutex::Autolock _l(mLock);
173    return mpAudioPolicy->set_device_connection_state(mpAudioPolicy, device,
174                                                      state, device_address);
175}
176
177audio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState(
178                                                              audio_devices_t device,
179                                                              const char *device_address)
180{
181    if (mpAudioPolicy == NULL) {
182        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
183    }
184    return mpAudioPolicy->get_device_connection_state(mpAudioPolicy, device,
185                                                      device_address);
186}
187
188status_t AudioPolicyService::setPhoneState(audio_mode_t state)
189{
190    if (mpAudioPolicy == NULL) {
191        return NO_INIT;
192    }
193    if (!checkPermission()) {
194        return PERMISSION_DENIED;
195    }
196    if (uint32_t(state) >= AUDIO_MODE_CNT) {
197        return BAD_VALUE;
198    }
199
200    ALOGV("setPhoneState() tid %d", gettid());
201
202    // TODO: check if it is more appropriate to do it in platform specific policy manager
203    AudioSystem::setMode(state);
204
205    Mutex::Autolock _l(mLock);
206    mpAudioPolicy->set_phone_state(mpAudioPolicy, state);
207    return NO_ERROR;
208}
209
210status_t AudioPolicyService::setRingerMode(uint32_t mode, uint32_t mask)
211{
212    if (mpAudioPolicy == NULL) {
213        return NO_INIT;
214    }
215    if (!checkPermission()) {
216        return PERMISSION_DENIED;
217    }
218
219    mpAudioPolicy->set_ringer_mode(mpAudioPolicy, mode, mask);
220    return NO_ERROR;
221}
222
223status_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage,
224                                         audio_policy_forced_cfg_t config)
225{
226    if (mpAudioPolicy == NULL) {
227        return NO_INIT;
228    }
229    if (!checkPermission()) {
230        return PERMISSION_DENIED;
231    }
232    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
233        return BAD_VALUE;
234    }
235    if (config < 0 || config >= AUDIO_POLICY_FORCE_CFG_CNT) {
236        return BAD_VALUE;
237    }
238    ALOGV("setForceUse() tid %d", gettid());
239    Mutex::Autolock _l(mLock);
240    mpAudioPolicy->set_force_use(mpAudioPolicy, usage, config);
241    return NO_ERROR;
242}
243
244audio_policy_forced_cfg_t AudioPolicyService::getForceUse(audio_policy_force_use_t usage)
245{
246    if (mpAudioPolicy == NULL) {
247        return AUDIO_POLICY_FORCE_NONE;
248    }
249    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
250        return AUDIO_POLICY_FORCE_NONE;
251    }
252    return mpAudioPolicy->get_force_use(mpAudioPolicy, usage);
253}
254
255audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
256                                    uint32_t samplingRate,
257                                    uint32_t format,
258                                    uint32_t channels,
259                                    audio_policy_output_flags_t flags)
260{
261    if (mpAudioPolicy == NULL) {
262        return 0;
263    }
264    ALOGV("getOutput() tid %d", gettid());
265    Mutex::Autolock _l(mLock);
266    return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate, format, channels, flags);
267}
268
269status_t AudioPolicyService::startOutput(audio_io_handle_t output,
270                                         audio_stream_type_t stream,
271                                         int session)
272{
273    if (mpAudioPolicy == NULL) {
274        return NO_INIT;
275    }
276    ALOGV("startOutput() tid %d", gettid());
277    Mutex::Autolock _l(mLock);
278    return mpAudioPolicy->start_output(mpAudioPolicy, output, stream, session);
279}
280
281status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
282                                        audio_stream_type_t stream,
283                                        int session)
284{
285    if (mpAudioPolicy == NULL) {
286        return NO_INIT;
287    }
288    ALOGV("stopOutput() tid %d", gettid());
289    Mutex::Autolock _l(mLock);
290    return mpAudioPolicy->stop_output(mpAudioPolicy, output, stream, session);
291}
292
293void AudioPolicyService::releaseOutput(audio_io_handle_t output)
294{
295    if (mpAudioPolicy == NULL) {
296        return;
297    }
298    ALOGV("releaseOutput() tid %d", gettid());
299    Mutex::Autolock _l(mLock);
300    mpAudioPolicy->release_output(mpAudioPolicy, output);
301}
302
303audio_io_handle_t AudioPolicyService::getInput(int inputSource,
304                                    uint32_t samplingRate,
305                                    uint32_t format,
306                                    uint32_t channels,
307                                    audio_in_acoustics_t acoustics,
308                                    int audioSession)
309{
310    if (mpAudioPolicy == NULL) {
311        return 0;
312    }
313    Mutex::Autolock _l(mLock);
314    audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
315                                                       format, channels, acoustics);
316
317    if (input == 0) {
318        return input;
319    }
320    // create audio pre processors according to input source
321    ssize_t index = mInputSources.indexOfKey((audio_source_t)inputSource);
322    if (index < 0) {
323        return input;
324    }
325    ssize_t idx = mInputs.indexOfKey(input);
326    InputDesc *inputDesc;
327    if (idx < 0) {
328        inputDesc = new InputDesc();
329        inputDesc->mSessionId = audioSession;
330        mInputs.add(input, inputDesc);
331    } else {
332        inputDesc = mInputs.valueAt(idx);
333    }
334
335    Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
336    for (size_t i = 0; i < effects.size(); i++) {
337        EffectDesc *effect = effects[i];
338        sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
339        status_t status = fx->initCheck();
340        if (status != NO_ERROR && status != ALREADY_EXISTS) {
341            ALOGW("Failed to create Fx %s on input %d", effect->mName, input);
342            // fx goes out of scope and strong ref on AudioEffect is released
343            continue;
344        }
345        for (size_t j = 0; j < effect->mParams.size(); j++) {
346            fx->setParameter(effect->mParams[j]);
347        }
348        inputDesc->mEffects.add(fx);
349    }
350    setPreProcessorEnabled(inputDesc, true);
351    return input;
352}
353
354status_t AudioPolicyService::startInput(audio_io_handle_t input)
355{
356    if (mpAudioPolicy == NULL) {
357        return NO_INIT;
358    }
359    Mutex::Autolock _l(mLock);
360
361    return mpAudioPolicy->start_input(mpAudioPolicy, input);
362}
363
364status_t AudioPolicyService::stopInput(audio_io_handle_t input)
365{
366    if (mpAudioPolicy == NULL) {
367        return NO_INIT;
368    }
369    Mutex::Autolock _l(mLock);
370
371    return mpAudioPolicy->stop_input(mpAudioPolicy, input);
372}
373
374void AudioPolicyService::releaseInput(audio_io_handle_t input)
375{
376    if (mpAudioPolicy == NULL) {
377        return;
378    }
379    Mutex::Autolock _l(mLock);
380    mpAudioPolicy->release_input(mpAudioPolicy, input);
381
382    ssize_t index = mInputs.indexOfKey(input);
383    if (index < 0) {
384        return;
385    }
386    InputDesc *inputDesc = mInputs.valueAt(index);
387    setPreProcessorEnabled(inputDesc, false);
388    inputDesc->mEffects.clear();
389    delete inputDesc;
390    mInputs.removeItemsAt(index);
391}
392
393status_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,
394                                            int indexMin,
395                                            int indexMax)
396{
397    if (mpAudioPolicy == NULL) {
398        return NO_INIT;
399    }
400    if (!checkPermission()) {
401        return PERMISSION_DENIED;
402    }
403    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
404        return BAD_VALUE;
405    }
406    mpAudioPolicy->init_stream_volume(mpAudioPolicy, stream, indexMin, indexMax);
407    return NO_ERROR;
408}
409
410status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,
411                                                  int index,
412                                                  audio_devices_t device)
413{
414    if (mpAudioPolicy == NULL) {
415        return NO_INIT;
416    }
417    if (!checkPermission()) {
418        return PERMISSION_DENIED;
419    }
420    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
421        return BAD_VALUE;
422    }
423
424    if (mpAudioPolicy->set_stream_volume_index_for_device) {
425        return mpAudioPolicy->set_stream_volume_index_for_device(mpAudioPolicy,
426                                                                stream,
427                                                                index,
428                                                                device);
429    } else {
430        return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index);
431    }
432}
433
434status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,
435                                                  int *index,
436                                                  audio_devices_t device)
437{
438    if (mpAudioPolicy == NULL) {
439        return NO_INIT;
440    }
441    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
442        return BAD_VALUE;
443    }
444    if (mpAudioPolicy->get_stream_volume_index_for_device) {
445        return mpAudioPolicy->get_stream_volume_index_for_device(mpAudioPolicy,
446                                                                stream,
447                                                                index,
448                                                                device);
449    } else {
450        return mpAudioPolicy->get_stream_volume_index(mpAudioPolicy, stream, index);
451    }
452}
453
454uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
455{
456    if (mpAudioPolicy == NULL) {
457        return 0;
458    }
459    return mpAudioPolicy->get_strategy_for_stream(mpAudioPolicy, stream);
460}
461
462uint32_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
463{
464    if (mpAudioPolicy == NULL) {
465        return 0;
466    }
467    return mpAudioPolicy->get_devices_for_stream(mpAudioPolicy, stream);
468}
469
470audio_io_handle_t AudioPolicyService::getOutputForEffect(effect_descriptor_t *desc)
471{
472    if (mpAudioPolicy == NULL) {
473        return NO_INIT;
474    }
475    Mutex::Autolock _l(mLock);
476    return mpAudioPolicy->get_output_for_effect(mpAudioPolicy, desc);
477}
478
479status_t AudioPolicyService::registerEffect(effect_descriptor_t *desc,
480                                audio_io_handle_t io,
481                                uint32_t strategy,
482                                int session,
483                                int id)
484{
485    if (mpAudioPolicy == NULL) {
486        return NO_INIT;
487    }
488    return mpAudioPolicy->register_effect(mpAudioPolicy, desc, io, strategy, session, id);
489}
490
491status_t AudioPolicyService::unregisterEffect(int id)
492{
493    if (mpAudioPolicy == NULL) {
494        return NO_INIT;
495    }
496    return mpAudioPolicy->unregister_effect(mpAudioPolicy, id);
497}
498
499status_t AudioPolicyService::setEffectEnabled(int id, bool enabled)
500{
501    if (mpAudioPolicy == NULL) {
502        return NO_INIT;
503    }
504    return mpAudioPolicy->set_effect_enabled(mpAudioPolicy, id, enabled);
505}
506
507bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
508{
509    if (mpAudioPolicy == NULL) {
510        return 0;
511    }
512    Mutex::Autolock _l(mLock);
513    return mpAudioPolicy->is_stream_active(mpAudioPolicy, stream, inPastMs);
514}
515
516status_t AudioPolicyService::queryDefaultPreProcessing(int audioSession,
517                                                       effect_descriptor_t *descriptors,
518                                                       uint32_t *count)
519{
520
521    if (mpAudioPolicy == NULL) {
522        *count = 0;
523        return NO_INIT;
524    }
525    Mutex::Autolock _l(mLock);
526    status_t status = NO_ERROR;
527
528    size_t index;
529    for (index = 0; index < mInputs.size(); index++) {
530        if (mInputs.valueAt(index)->mSessionId == audioSession) {
531            break;
532        }
533    }
534    if (index == mInputs.size()) {
535        *count = 0;
536        return BAD_VALUE;
537    }
538    Vector< sp<AudioEffect> > effects = mInputs.valueAt(index)->mEffects;
539
540    for (size_t i = 0; i < effects.size(); i++) {
541        effect_descriptor_t desc = effects[i]->descriptor();
542        if (i < *count) {
543            memcpy(descriptors + i, &desc, sizeof(effect_descriptor_t));
544        }
545    }
546    if (effects.size() > *count) {
547        status = NO_MEMORY;
548    }
549    *count = effects.size();
550    return status;
551}
552
553void AudioPolicyService::binderDied(const wp<IBinder>& who) {
554    ALOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(),
555            IPCThreadState::self()->getCallingPid());
556}
557
558static bool tryLock(Mutex& mutex)
559{
560    bool locked = false;
561    for (int i = 0; i < kDumpLockRetries; ++i) {
562        if (mutex.tryLock() == NO_ERROR) {
563            locked = true;
564            break;
565        }
566        usleep(kDumpLockSleepUs);
567    }
568    return locked;
569}
570
571status_t AudioPolicyService::dumpInternals(int fd)
572{
573    const size_t SIZE = 256;
574    char buffer[SIZE];
575    String8 result;
576
577    snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpAudioPolicy);
578    result.append(buffer);
579    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
580    result.append(buffer);
581    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
582    result.append(buffer);
583
584    write(fd, result.string(), result.size());
585    return NO_ERROR;
586}
587
588status_t AudioPolicyService::dump(int fd, const Vector<String16>& args)
589{
590    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
591        dumpPermissionDenial(fd);
592    } else {
593        bool locked = tryLock(mLock);
594        if (!locked) {
595            String8 result(kDeadlockedString);
596            write(fd, result.string(), result.size());
597        }
598
599        dumpInternals(fd);
600        if (mAudioCommandThread != NULL) {
601            mAudioCommandThread->dump(fd);
602        }
603        if (mTonePlaybackThread != NULL) {
604            mTonePlaybackThread->dump(fd);
605        }
606
607        if (mpAudioPolicy) {
608            mpAudioPolicy->dump(mpAudioPolicy, fd);
609        }
610
611        if (locked) mLock.unlock();
612    }
613    return NO_ERROR;
614}
615
616status_t AudioPolicyService::dumpPermissionDenial(int fd)
617{
618    const size_t SIZE = 256;
619    char buffer[SIZE];
620    String8 result;
621    snprintf(buffer, SIZE, "Permission Denial: "
622            "can't dump AudioPolicyService from pid=%d, uid=%d\n",
623            IPCThreadState::self()->getCallingPid(),
624            IPCThreadState::self()->getCallingUid());
625    result.append(buffer);
626    write(fd, result.string(), result.size());
627    return NO_ERROR;
628}
629
630void AudioPolicyService::setPreProcessorEnabled(InputDesc *inputDesc, bool enabled)
631{
632    Vector<sp<AudioEffect> > fxVector = inputDesc->mEffects;
633    for (size_t i = 0; i < fxVector.size(); i++) {
634        sp<AudioEffect> fx = fxVector.itemAt(i);
635        fx->setEnabled(enabled);
636    }
637}
638
639status_t AudioPolicyService::onTransact(
640        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
641{
642    return BnAudioPolicyService::onTransact(code, data, reply, flags);
643}
644
645
646// -----------  AudioPolicyService::AudioCommandThread implementation ----------
647
648AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name)
649    : Thread(false), mName(name)
650{
651    mpToneGenerator = NULL;
652}
653
654
655AudioPolicyService::AudioCommandThread::~AudioCommandThread()
656{
657    if (mName != "" && !mAudioCommands.isEmpty()) {
658        release_wake_lock(mName.string());
659    }
660    mAudioCommands.clear();
661    if (mpToneGenerator != NULL) delete mpToneGenerator;
662}
663
664void AudioPolicyService::AudioCommandThread::onFirstRef()
665{
666    if (mName != "") {
667        run(mName.string(), ANDROID_PRIORITY_AUDIO);
668    } else {
669        run("AudioCommandThread", ANDROID_PRIORITY_AUDIO);
670    }
671}
672
673bool AudioPolicyService::AudioCommandThread::threadLoop()
674{
675    nsecs_t waitTime = INT64_MAX;
676
677    mLock.lock();
678    while (!exitPending())
679    {
680        while(!mAudioCommands.isEmpty()) {
681            nsecs_t curTime = systemTime();
682            // commands are sorted by increasing time stamp: execute them from index 0 and up
683            if (mAudioCommands[0]->mTime <= curTime) {
684                AudioCommand *command = mAudioCommands[0];
685                mAudioCommands.removeAt(0);
686                mLastCommand = *command;
687
688                switch (command->mCommand) {
689                case START_TONE: {
690                    mLock.unlock();
691                    ToneData *data = (ToneData *)command->mParam;
692                    ALOGV("AudioCommandThread() processing start tone %d on stream %d",
693                            data->mType, data->mStream);
694                    if (mpToneGenerator != NULL)
695                        delete mpToneGenerator;
696                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
697                    mpToneGenerator->startTone(data->mType);
698                    delete data;
699                    mLock.lock();
700                    }break;
701                case STOP_TONE: {
702                    mLock.unlock();
703                    ALOGV("AudioCommandThread() processing stop tone");
704                    if (mpToneGenerator != NULL) {
705                        mpToneGenerator->stopTone();
706                        delete mpToneGenerator;
707                        mpToneGenerator = NULL;
708                    }
709                    mLock.lock();
710                    }break;
711                case SET_VOLUME: {
712                    VolumeData *data = (VolumeData *)command->mParam;
713                    ALOGV("AudioCommandThread() processing set volume stream %d, \
714                            volume %f, output %d", data->mStream, data->mVolume, data->mIO);
715                    command->mStatus = AudioSystem::setStreamVolume(data->mStream,
716                                                                    data->mVolume,
717                                                                    data->mIO);
718                    if (command->mWaitStatus) {
719                        command->mCond.signal();
720                        mWaitWorkCV.wait(mLock);
721                    }
722                    delete data;
723                    }break;
724                case SET_PARAMETERS: {
725                     ParametersData *data = (ParametersData *)command->mParam;
726                     ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
727                             data->mKeyValuePairs.string(), data->mIO);
728                     command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
729                     if (command->mWaitStatus) {
730                         command->mCond.signal();
731                         mWaitWorkCV.wait(mLock);
732                     }
733                     delete data;
734                     }break;
735                case SET_VOICE_VOLUME: {
736                    VoiceVolumeData *data = (VoiceVolumeData *)command->mParam;
737                    ALOGV("AudioCommandThread() processing set voice volume volume %f",
738                            data->mVolume);
739                    command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
740                    if (command->mWaitStatus) {
741                        command->mCond.signal();
742                        mWaitWorkCV.wait(mLock);
743                    }
744                    delete data;
745                    }break;
746                default:
747                    ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
748                }
749                delete command;
750                waitTime = INT64_MAX;
751            } else {
752                waitTime = mAudioCommands[0]->mTime - curTime;
753                break;
754            }
755        }
756        // release delayed commands wake lock
757        if (mName != "" && mAudioCommands.isEmpty()) {
758            release_wake_lock(mName.string());
759        }
760        ALOGV("AudioCommandThread() going to sleep");
761        mWaitWorkCV.waitRelative(mLock, waitTime);
762        ALOGV("AudioCommandThread() waking up");
763    }
764    mLock.unlock();
765    return false;
766}
767
768status_t AudioPolicyService::AudioCommandThread::dump(int fd)
769{
770    const size_t SIZE = 256;
771    char buffer[SIZE];
772    String8 result;
773
774    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
775    result.append(buffer);
776    write(fd, result.string(), result.size());
777
778    bool locked = tryLock(mLock);
779    if (!locked) {
780        String8 result2(kCmdDeadlockedString);
781        write(fd, result2.string(), result2.size());
782    }
783
784    snprintf(buffer, SIZE, "- Commands:\n");
785    result = String8(buffer);
786    result.append("   Command Time        Wait pParam\n");
787    for (int i = 0; i < (int)mAudioCommands.size(); i++) {
788        mAudioCommands[i]->dump(buffer, SIZE);
789        result.append(buffer);
790    }
791    result.append("  Last Command\n");
792    mLastCommand.dump(buffer, SIZE);
793    result.append(buffer);
794
795    write(fd, result.string(), result.size());
796
797    if (locked) mLock.unlock();
798
799    return NO_ERROR;
800}
801
802void AudioPolicyService::AudioCommandThread::startToneCommand(int type, audio_stream_type_t stream)
803{
804    AudioCommand *command = new AudioCommand();
805    command->mCommand = START_TONE;
806    ToneData *data = new ToneData();
807    data->mType = type;
808    data->mStream = stream;
809    command->mParam = (void *)data;
810    command->mWaitStatus = false;
811    Mutex::Autolock _l(mLock);
812    insertCommand_l(command);
813    ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
814    mWaitWorkCV.signal();
815}
816
817void AudioPolicyService::AudioCommandThread::stopToneCommand()
818{
819    AudioCommand *command = new AudioCommand();
820    command->mCommand = STOP_TONE;
821    command->mParam = NULL;
822    command->mWaitStatus = false;
823    Mutex::Autolock _l(mLock);
824    insertCommand_l(command);
825    ALOGV("AudioCommandThread() adding tone stop");
826    mWaitWorkCV.signal();
827}
828
829status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
830                                                               float volume,
831                                                               int output,
832                                                               int delayMs)
833{
834    status_t status = NO_ERROR;
835
836    AudioCommand *command = new AudioCommand();
837    command->mCommand = SET_VOLUME;
838    VolumeData *data = new VolumeData();
839    data->mStream = stream;
840    data->mVolume = volume;
841    data->mIO = output;
842    command->mParam = data;
843    if (delayMs == 0) {
844        command->mWaitStatus = true;
845    } else {
846        command->mWaitStatus = false;
847    }
848    Mutex::Autolock _l(mLock);
849    insertCommand_l(command, delayMs);
850    ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
851            stream, volume, output);
852    mWaitWorkCV.signal();
853    if (command->mWaitStatus) {
854        command->mCond.wait(mLock);
855        status =  command->mStatus;
856        mWaitWorkCV.signal();
857    }
858    return status;
859}
860
861status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
862                                                                   const char *keyValuePairs,
863                                                                   int delayMs)
864{
865    status_t status = NO_ERROR;
866
867    AudioCommand *command = new AudioCommand();
868    command->mCommand = SET_PARAMETERS;
869    ParametersData *data = new ParametersData();
870    data->mIO = ioHandle;
871    data->mKeyValuePairs = String8(keyValuePairs);
872    command->mParam = data;
873    if (delayMs == 0) {
874        command->mWaitStatus = true;
875    } else {
876        command->mWaitStatus = false;
877    }
878    Mutex::Autolock _l(mLock);
879    insertCommand_l(command, delayMs);
880    ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
881            keyValuePairs, ioHandle, delayMs);
882    mWaitWorkCV.signal();
883    if (command->mWaitStatus) {
884        command->mCond.wait(mLock);
885        status =  command->mStatus;
886        mWaitWorkCV.signal();
887    }
888    return status;
889}
890
891status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
892{
893    status_t status = NO_ERROR;
894
895    AudioCommand *command = new AudioCommand();
896    command->mCommand = SET_VOICE_VOLUME;
897    VoiceVolumeData *data = new VoiceVolumeData();
898    data->mVolume = volume;
899    command->mParam = data;
900    if (delayMs == 0) {
901        command->mWaitStatus = true;
902    } else {
903        command->mWaitStatus = false;
904    }
905    Mutex::Autolock _l(mLock);
906    insertCommand_l(command, delayMs);
907    ALOGV("AudioCommandThread() adding set voice volume volume %f", volume);
908    mWaitWorkCV.signal();
909    if (command->mWaitStatus) {
910        command->mCond.wait(mLock);
911        status =  command->mStatus;
912        mWaitWorkCV.signal();
913    }
914    return status;
915}
916
917// insertCommand_l() must be called with mLock held
918void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs)
919{
920    ssize_t i;
921    Vector <AudioCommand *> removedCommands;
922
923    command->mTime = systemTime() + milliseconds(delayMs);
924
925    // acquire wake lock to make sure delayed commands are processed
926    if (mName != "" && mAudioCommands.isEmpty()) {
927        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
928    }
929
930    // check same pending commands with later time stamps and eliminate them
931    for (i = mAudioCommands.size()-1; i >= 0; i--) {
932        AudioCommand *command2 = mAudioCommands[i];
933        // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
934        if (command2->mTime <= command->mTime) break;
935        if (command2->mCommand != command->mCommand) continue;
936
937        switch (command->mCommand) {
938        case SET_PARAMETERS: {
939            ParametersData *data = (ParametersData *)command->mParam;
940            ParametersData *data2 = (ParametersData *)command2->mParam;
941            if (data->mIO != data2->mIO) break;
942            ALOGV("Comparing parameter command %s to new command %s",
943                    data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
944            AudioParameter param = AudioParameter(data->mKeyValuePairs);
945            AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
946            for (size_t j = 0; j < param.size(); j++) {
947               String8 key;
948               String8 value;
949               param.getAt(j, key, value);
950               for (size_t k = 0; k < param2.size(); k++) {
951                  String8 key2;
952                  String8 value2;
953                  param2.getAt(k, key2, value2);
954                  if (key2 == key) {
955                      param2.remove(key2);
956                      ALOGV("Filtering out parameter %s", key2.string());
957                      break;
958                  }
959               }
960            }
961            // if all keys have been filtered out, remove the command.
962            // otherwise, update the key value pairs
963            if (param2.size() == 0) {
964                removedCommands.add(command2);
965            } else {
966                data2->mKeyValuePairs = param2.toString();
967            }
968        } break;
969
970        case SET_VOLUME: {
971            VolumeData *data = (VolumeData *)command->mParam;
972            VolumeData *data2 = (VolumeData *)command2->mParam;
973            if (data->mIO != data2->mIO) break;
974            if (data->mStream != data2->mStream) break;
975            ALOGV("Filtering out volume command on output %d for stream %d",
976                    data->mIO, data->mStream);
977            removedCommands.add(command2);
978        } break;
979        case START_TONE:
980        case STOP_TONE:
981        default:
982            break;
983        }
984    }
985
986    // remove filtered commands
987    for (size_t j = 0; j < removedCommands.size(); j++) {
988        // removed commands always have time stamps greater than current command
989        for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
990            if (mAudioCommands[k] == removedCommands[j]) {
991                ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
992                mAudioCommands.removeAt(k);
993                break;
994            }
995        }
996    }
997    removedCommands.clear();
998
999    // insert command at the right place according to its time stamp
1000    ALOGV("inserting command: %d at index %d, num commands %d",
1001            command->mCommand, (int)i+1, mAudioCommands.size());
1002    mAudioCommands.insertAt(command, i + 1);
1003}
1004
1005void AudioPolicyService::AudioCommandThread::exit()
1006{
1007    ALOGV("AudioCommandThread::exit");
1008    {
1009        AutoMutex _l(mLock);
1010        requestExit();
1011        mWaitWorkCV.signal();
1012    }
1013    requestExitAndWait();
1014}
1015
1016void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
1017{
1018    snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
1019            mCommand,
1020            (int)ns2s(mTime),
1021            (int)ns2ms(mTime)%1000,
1022            mWaitStatus,
1023            mParam);
1024}
1025
1026/******* helpers for the service_ops callbacks defined below *********/
1027void AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
1028                                       const char *keyValuePairs,
1029                                       int delayMs)
1030{
1031    mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs,
1032                                           delayMs);
1033}
1034
1035int AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
1036                                        float volume,
1037                                        audio_io_handle_t output,
1038                                        int delayMs)
1039{
1040    return (int)mAudioCommandThread->volumeCommand(stream, volume,
1041                                                   (int)output, delayMs);
1042}
1043
1044int AudioPolicyService::startTone(audio_policy_tone_t tone,
1045                                  audio_stream_type_t stream)
1046{
1047    if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION)
1048        ALOGE("startTone: illegal tone requested (%d)", tone);
1049    if (stream != AUDIO_STREAM_VOICE_CALL)
1050        ALOGE("startTone: illegal stream (%d) requested for tone %d", stream,
1051             tone);
1052    mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING,
1053                                          AUDIO_STREAM_VOICE_CALL);
1054    return 0;
1055}
1056
1057int AudioPolicyService::stopTone()
1058{
1059    mTonePlaybackThread->stopToneCommand();
1060    return 0;
1061}
1062
1063int AudioPolicyService::setVoiceVolume(float volume, int delayMs)
1064{
1065    return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
1066}
1067
1068// ----------------------------------------------------------------------------
1069// Audio pre-processing configuration
1070// ----------------------------------------------------------------------------
1071
1072const char *AudioPolicyService::kInputSourceNames[AUDIO_SOURCE_CNT -1] = {
1073    MIC_SRC_TAG,
1074    VOICE_UL_SRC_TAG,
1075    VOICE_DL_SRC_TAG,
1076    VOICE_CALL_SRC_TAG,
1077    CAMCORDER_SRC_TAG,
1078    VOICE_REC_SRC_TAG,
1079    VOICE_COMM_SRC_TAG
1080};
1081
1082// returns the audio_source_t enum corresponding to the input source name or
1083// AUDIO_SOURCE_CNT is no match found
1084audio_source_t AudioPolicyService::inputSourceNameToEnum(const char *name)
1085{
1086    int i;
1087    for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) {
1088        if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) {
1089            ALOGV("inputSourceNameToEnum found source %s %d", name, i);
1090            break;
1091        }
1092    }
1093    return (audio_source_t)i;
1094}
1095
1096size_t AudioPolicyService::growParamSize(char *param,
1097                                         size_t size,
1098                                         size_t *curSize,
1099                                         size_t *totSize)
1100{
1101    // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int)
1102    size_t pos = ((*curSize - 1 ) / size + 1) * size;
1103
1104    if (pos + size > *totSize) {
1105        while (pos + size > *totSize) {
1106            *totSize += ((*totSize + 7) / 8) * 4;
1107        }
1108        param = (char *)realloc(param, *totSize);
1109    }
1110    *curSize = pos + size;
1111    return pos;
1112}
1113
1114size_t AudioPolicyService::readParamValue(cnode *node,
1115                                          char *param,
1116                                          size_t *curSize,
1117                                          size_t *totSize)
1118{
1119    if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) {
1120        size_t pos = growParamSize(param, sizeof(short), curSize, totSize);
1121        *(short *)((char *)param + pos) = (short)atoi(node->value);
1122        ALOGV("readParamValue() reading short %d", *(short *)((char *)param + pos));
1123        return sizeof(short);
1124    } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) {
1125        size_t pos = growParamSize(param, sizeof(int), curSize, totSize);
1126        *(int *)((char *)param + pos) = atoi(node->value);
1127        ALOGV("readParamValue() reading int %d", *(int *)((char *)param + pos));
1128        return sizeof(int);
1129    } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) {
1130        size_t pos = growParamSize(param, sizeof(float), curSize, totSize);
1131        *(float *)((char *)param + pos) = (float)atof(node->value);
1132        ALOGV("readParamValue() reading float %f",*(float *)((char *)param + pos));
1133        return sizeof(float);
1134    } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) {
1135        size_t pos = growParamSize(param, sizeof(bool), curSize, totSize);
1136        if (strncmp(node->value, "false", strlen("false") + 1) == 0) {
1137            *(bool *)((char *)param + pos) = false;
1138        } else {
1139            *(bool *)((char *)param + pos) = true;
1140        }
1141        ALOGV("readParamValue() reading bool %s",*(bool *)((char *)param + pos) ? "true" : "false");
1142        return sizeof(bool);
1143    } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) {
1144        size_t len = strnlen(node->value, EFFECT_STRING_LEN_MAX);
1145        if (*curSize + len + 1 > *totSize) {
1146            *totSize = *curSize + len + 1;
1147            param = (char *)realloc(param, *totSize);
1148        }
1149        strncpy(param + *curSize, node->value, len);
1150        *curSize += len;
1151        param[*curSize] = '\0';
1152        ALOGV("readParamValue() reading string %s", param + *curSize - len);
1153        return len;
1154    }
1155    ALOGW("readParamValue() unknown param type %s", node->name);
1156    return 0;
1157}
1158
1159effect_param_t *AudioPolicyService::loadEffectParameter(cnode *root)
1160{
1161    cnode *param;
1162    cnode *value;
1163    size_t curSize = sizeof(effect_param_t);
1164    size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int);
1165    effect_param_t *fx_param = (effect_param_t *)malloc(totSize);
1166
1167    param = config_find(root, PARAM_TAG);
1168    value = config_find(root, VALUE_TAG);
1169    if (param == NULL && value == NULL) {
1170        // try to parse simple parameter form {int int}
1171        param = root->first_child;
1172        if (param) {
1173            // Note: that a pair of random strings is read as 0 0
1174            int *ptr = (int *)fx_param->data;
1175            int *ptr2 = (int *)((char *)param + sizeof(effect_param_t));
1176            ALOGW("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2);
1177            *ptr++ = atoi(param->name);
1178            *ptr = atoi(param->value);
1179            fx_param->psize = sizeof(int);
1180            fx_param->vsize = sizeof(int);
1181            return fx_param;
1182        }
1183    }
1184    if (param == NULL || value == NULL) {
1185        ALOGW("loadEffectParameter() invalid parameter description %s", root->name);
1186        goto error;
1187    }
1188
1189    fx_param->psize = 0;
1190    param = param->first_child;
1191    while (param) {
1192        ALOGV("loadEffectParameter() reading param of type %s", param->name);
1193        size_t size = readParamValue(param, (char *)fx_param, &curSize, &totSize);
1194        if (size == 0) {
1195            goto error;
1196        }
1197        fx_param->psize += size;
1198        param = param->next;
1199    }
1200
1201    // align start of value field on 32 bit boundary
1202    curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int);
1203
1204    fx_param->vsize = 0;
1205    value = value->first_child;
1206    while (value) {
1207        ALOGV("loadEffectParameter() reading value of type %s", value->name);
1208        size_t size = readParamValue(value, (char *)fx_param, &curSize, &totSize);
1209        if (size == 0) {
1210            goto error;
1211        }
1212        fx_param->vsize += size;
1213        value = value->next;
1214    }
1215
1216    return fx_param;
1217
1218error:
1219    delete fx_param;
1220    return NULL;
1221}
1222
1223void AudioPolicyService::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params)
1224{
1225    cnode *node = root->first_child;
1226    while (node) {
1227        ALOGV("loadEffectParameters() loading param %s", node->name);
1228        effect_param_t *param = loadEffectParameter(node);
1229        if (param == NULL) {
1230            node = node->next;
1231            continue;
1232        }
1233        params.add(param);
1234        node = node->next;
1235    }
1236}
1237
1238AudioPolicyService::InputSourceDesc *AudioPolicyService::loadInputSource(
1239                                                            cnode *root,
1240                                                            const Vector <EffectDesc *>& effects)
1241{
1242    cnode *node = root->first_child;
1243    if (node == NULL) {
1244        ALOGW("loadInputSource() empty element %s", root->name);
1245        return NULL;
1246    }
1247    InputSourceDesc *source = new InputSourceDesc();
1248    while (node) {
1249        size_t i;
1250        for (i = 0; i < effects.size(); i++) {
1251            if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) {
1252                ALOGV("loadInputSource() found effect %s in list", node->name);
1253                break;
1254            }
1255        }
1256        if (i == effects.size()) {
1257            ALOGV("loadInputSource() effect %s not in list", node->name);
1258            node = node->next;
1259            continue;
1260        }
1261        EffectDesc *effect = new EffectDesc(*effects[i]);
1262        loadEffectParameters(node, effect->mParams);
1263        ALOGV("loadInputSource() adding effect %s uuid %08x", effect->mName, effect->mUuid.timeLow);
1264        source->mEffects.add(effect);
1265        node = node->next;
1266    }
1267    if (source->mEffects.size() == 0) {
1268        ALOGW("loadInputSource() no valid effects found in source %s", root->name);
1269        delete source;
1270        return NULL;
1271    }
1272    return source;
1273}
1274
1275status_t AudioPolicyService::loadInputSources(cnode *root, const Vector <EffectDesc *>& effects)
1276{
1277    cnode *node = config_find(root, PREPROCESSING_TAG);
1278    if (node == NULL) {
1279        return -ENOENT;
1280    }
1281    node = node->first_child;
1282    while (node) {
1283        audio_source_t source = inputSourceNameToEnum(node->name);
1284        if (source == AUDIO_SOURCE_CNT) {
1285            ALOGW("loadInputSources() invalid input source %s", node->name);
1286            node = node->next;
1287            continue;
1288        }
1289        ALOGV("loadInputSources() loading input source %s", node->name);
1290        InputSourceDesc *desc = loadInputSource(node, effects);
1291        if (desc == NULL) {
1292            node = node->next;
1293            continue;
1294        }
1295        mInputSources.add(source, desc);
1296        node = node->next;
1297    }
1298    return NO_ERROR;
1299}
1300
1301AudioPolicyService::EffectDesc *AudioPolicyService::loadEffect(cnode *root)
1302{
1303    cnode *node = config_find(root, UUID_TAG);
1304    if (node == NULL) {
1305        return NULL;
1306    }
1307    effect_uuid_t uuid;
1308    if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) {
1309        ALOGW("loadEffect() invalid uuid %s", node->value);
1310        return NULL;
1311    }
1312    EffectDesc *effect = new EffectDesc();
1313    effect->mName = strdup(root->name);
1314    memcpy(&effect->mUuid, &uuid, sizeof(effect_uuid_t));
1315
1316    return effect;
1317}
1318
1319status_t AudioPolicyService::loadEffects(cnode *root, Vector <EffectDesc *>& effects)
1320{
1321    cnode *node = config_find(root, EFFECTS_TAG);
1322    if (node == NULL) {
1323        return -ENOENT;
1324    }
1325    node = node->first_child;
1326    while (node) {
1327        ALOGV("loadEffects() loading effect %s", node->name);
1328        EffectDesc *effect = loadEffect(node);
1329        if (effect == NULL) {
1330            node = node->next;
1331            continue;
1332        }
1333        effects.add(effect);
1334        node = node->next;
1335    }
1336    return NO_ERROR;
1337}
1338
1339status_t AudioPolicyService::loadPreProcessorConfig(const char *path)
1340{
1341    cnode *root;
1342    char *data;
1343
1344    data = (char *)load_file(path, NULL);
1345    if (data == NULL) {
1346        return -ENODEV;
1347    }
1348    root = config_node("", "");
1349    config_load(root, data);
1350
1351    Vector <EffectDesc *> effects;
1352    loadEffects(root, effects);
1353    loadInputSources(root, effects);
1354
1355    config_free(root);
1356    free(root);
1357    free(data);
1358
1359    return NO_ERROR;
1360}
1361
1362/* implementation of the interface to the policy manager */
1363extern "C" {
1364
1365static audio_io_handle_t aps_open_output(void *service,
1366                                             uint32_t *pDevices,
1367                                             uint32_t *pSamplingRate,
1368                                             uint32_t *pFormat,
1369                                             uint32_t *pChannels,
1370                                             uint32_t *pLatencyMs,
1371                                             audio_policy_output_flags_t flags)
1372{
1373    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1374    if (af == NULL) {
1375        ALOGW("%s: could not get AudioFlinger", __func__);
1376        return 0;
1377    }
1378
1379    return af->openOutput(pDevices, pSamplingRate, pFormat, pChannels,
1380                          pLatencyMs, flags);
1381}
1382
1383static audio_io_handle_t aps_open_dup_output(void *service,
1384                                                 audio_io_handle_t output1,
1385                                                 audio_io_handle_t output2)
1386{
1387    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1388    if (af == NULL) {
1389        ALOGW("%s: could not get AudioFlinger", __func__);
1390        return 0;
1391    }
1392    return af->openDuplicateOutput(output1, output2);
1393}
1394
1395static int aps_close_output(void *service, audio_io_handle_t output)
1396{
1397    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1398    if (af == NULL)
1399        return PERMISSION_DENIED;
1400
1401    return af->closeOutput(output);
1402}
1403
1404static int aps_suspend_output(void *service, audio_io_handle_t output)
1405{
1406    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1407    if (af == NULL) {
1408        ALOGW("%s: could not get AudioFlinger", __func__);
1409        return PERMISSION_DENIED;
1410    }
1411
1412    return af->suspendOutput(output);
1413}
1414
1415static int aps_restore_output(void *service, audio_io_handle_t output)
1416{
1417    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1418    if (af == NULL) {
1419        ALOGW("%s: could not get AudioFlinger", __func__);
1420        return PERMISSION_DENIED;
1421    }
1422
1423    return af->restoreOutput(output);
1424}
1425
1426static audio_io_handle_t aps_open_input(void *service,
1427                                            uint32_t *pDevices,
1428                                            uint32_t *pSamplingRate,
1429                                            uint32_t *pFormat,
1430                                            uint32_t *pChannels,
1431                                            uint32_t acoustics)
1432{
1433    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1434    if (af == NULL) {
1435        ALOGW("%s: could not get AudioFlinger", __func__);
1436        return 0;
1437    }
1438
1439    return af->openInput(pDevices, pSamplingRate, pFormat, pChannels,
1440                         acoustics);
1441}
1442
1443static int aps_close_input(void *service, audio_io_handle_t input)
1444{
1445    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1446    if (af == NULL)
1447        return PERMISSION_DENIED;
1448
1449    return af->closeInput(input);
1450}
1451
1452static int aps_set_stream_output(void *service, audio_stream_type_t stream,
1453                                     audio_io_handle_t output)
1454{
1455    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1456    if (af == NULL)
1457        return PERMISSION_DENIED;
1458
1459    return af->setStreamOutput(stream, output);
1460}
1461
1462static int aps_move_effects(void *service, int session,
1463                                audio_io_handle_t src_output,
1464                                audio_io_handle_t dst_output)
1465{
1466    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1467    if (af == NULL)
1468        return PERMISSION_DENIED;
1469
1470    return af->moveEffects(session, (int)src_output, (int)dst_output);
1471}
1472
1473static char * aps_get_parameters(void *service, audio_io_handle_t io_handle,
1474                                     const char *keys)
1475{
1476    String8 result = AudioSystem::getParameters(io_handle, String8(keys));
1477    return strdup(result.string());
1478}
1479
1480static void aps_set_parameters(void *service, audio_io_handle_t io_handle,
1481                                   const char *kv_pairs, int delay_ms)
1482{
1483    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
1484
1485    audioPolicyService->setParameters(io_handle, kv_pairs, delay_ms);
1486}
1487
1488static int aps_set_stream_volume(void *service, audio_stream_type_t stream,
1489                                     float volume, audio_io_handle_t output,
1490                                     int delay_ms)
1491{
1492    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
1493
1494    return audioPolicyService->setStreamVolume(stream, volume, output,
1495                                               delay_ms);
1496}
1497
1498static int aps_start_tone(void *service, audio_policy_tone_t tone,
1499                              audio_stream_type_t stream)
1500{
1501    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
1502
1503    return audioPolicyService->startTone(tone, stream);
1504}
1505
1506static int aps_stop_tone(void *service)
1507{
1508    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
1509
1510    return audioPolicyService->stopTone();
1511}
1512
1513static int aps_set_voice_volume(void *service, float volume, int delay_ms)
1514{
1515    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
1516
1517    return audioPolicyService->setVoiceVolume(volume, delay_ms);
1518}
1519
1520}; // extern "C"
1521
1522namespace {
1523    struct audio_policy_service_ops aps_ops = {
1524        open_output           : aps_open_output,
1525        open_duplicate_output : aps_open_dup_output,
1526        close_output          : aps_close_output,
1527        suspend_output        : aps_suspend_output,
1528        restore_output        : aps_restore_output,
1529        open_input            : aps_open_input,
1530        close_input           : aps_close_input,
1531        set_stream_volume     : aps_set_stream_volume,
1532        set_stream_output     : aps_set_stream_output,
1533        set_parameters        : aps_set_parameters,
1534        get_parameters        : aps_get_parameters,
1535        start_tone            : aps_start_tone,
1536        stop_tone             : aps_stop_tone,
1537        set_voice_volume      : aps_set_voice_volume,
1538        move_effects          : aps_move_effects,
1539    };
1540}; // namespace <unnamed>
1541
1542}; // namespace android
1543