AudioPolicyService.cpp revision 657ff61389d7316f798d4abe03efac56fd528d91
165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian/*
2d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * Copyright (C) 2009 The Android Open Source Project
3d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk *
4d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License");
5d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * you may not use this file except in compliance with the License.
6d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * You may obtain a copy of the License at
7d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk *
8d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk *      http://www.apache.org/licenses/LICENSE-2.0
9d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk *
10d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * Unless required by applicable law or agreed to in writing, software
11d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS,
12d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * See the License for the specific language governing permissions and
14d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk * limitations under the License.
15d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk */
1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "AudioPolicyService"
18a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala//#define LOG_NDEBUG 0
198951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
2065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "Configuration.h"
21cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#undef __STRICT_ANSI__
22cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#define __STDINT_LIMITS
2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define __STDC_LIMIT_MACROS
24cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#include <stdint.h>
25cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
26cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#include <sys/time.h>
2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h>
28cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#include <utils/Log.h>
2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/properties.h>
3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h>
31d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#include <utils/String16.h>
32d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#include <utils/threads.h>
33d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#include "AudioPolicyService.h"
349c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo#include "ServiceUtilities.h"
352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala#include <hardware_legacy/power.h>
36a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov#include <media/AudioEffect.h>
37ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala#include <media/EffectsFactoryApi.h>
3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware/hardware.h>
4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <system/audio.h>
4165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <system/audio_policy.h>
42a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov#include <hardware/audio_policy.h>
43cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk#include <audio_effects/audio_effects_conf.h>
44a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov#include <media/AudioParameter.h>
4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
46b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatranamespace android {
47a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
48df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopianstatic const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n";
4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n";
50d89821ec5481e0640d84bfe3e29a1254a52ca683Eino-Ville Talvala
5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
521b86fe063badb5f28c467ade39be0f4008688947Andreas Huberstatic const int kDumpLockSleepUs = 20000;
5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5499e69716215cd0665379bc90d708f2ea8689831dRuben Brunkstatic const nsecs_t kAudioCommandTimeout = 3000000000LL; // 3 seconds
5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace {
5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    extern struct audio_policy_service_ops aps_ops;
58d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk};
5998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen
60d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk// ----------------------------------------------------------------------------
61b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
622f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville TalvalaAudioPolicyService::AudioPolicyService()
63b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian      mAudioPolicyManager(NULL), mAudioPolicyClient(NULL)
6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
667b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala    char value[PROPERTY_VALUE_MAX];
677b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala    const struct hw_module_t *module;
687b82efe7a376c882f8f938e1c41b8311a8cdda4aEino-Ville Talvala    int forced_val;
69ff3e31d2b100d8efd969b358b18e4405c49dd10dIgor Murashkin    int rc;
7065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
710dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
720dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // start tone playback thread
740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
7565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // start audio commands thread
7665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
77d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    // start output activity command thread
78f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
79f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
80e8c96c765b95ec7dcd10732621a825fce05960c6Eino-Ville Talvala#ifdef USE_LEGACY_AUDIO_POLICY
81f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    ALOGI("AudioPolicyService CSTOR in legacy mode");
82f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
83f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    /* instantiate the audio policy manager */
84d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
8565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (rc) {
8665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
885e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala    rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
8965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
90b8a805261bf0282e992d3608035e47d05a898710Steve Block    if (rc) {
91b8a805261bf0282e992d3608035e47d05a898710Steve Block        return;
9265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
9365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
9565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                               &mpAudioPolicy);
9665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));
97d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (rc) {
98d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return;
99d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
100d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
101d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    rc = mpAudioPolicy->init_check(mpAudioPolicy);
102d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc));
103d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (rc) {
104d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        return;
105d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
106d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    ALOGI("Loaded audio policy from %s (%s)", module->name, module->id);
107d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#else
10865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGI("AudioPolicyService CSTOR in new mode");
10965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
110a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mAudioPolicyClient = new AudioPolicyClient(this);
111a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    mAudioPolicyManager = new AudioPolicyManager(mAudioPolicyClient);
11249c9705a7987b94bd53fddd4834f5f534cf946f7Eino-Ville Talvala#endif
11349c9705a7987b94bd53fddd4834f5f534cf946f7Eino-Ville Talvala
114c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    // load audio pre processing modules
115f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
116df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
117cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
1188951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
11965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
1208951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev}
1218951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
122cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkAudioPolicyService::~AudioPolicyService()
123634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
1248951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    mTonePlaybackThread->exit();
12565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioCommandThread->exit();
12699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    mOutputCommandThread->exit();
12799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk
12899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    // release audio pre processing resources
12999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk    for (size_t i = 0; i < mInputSources.size(); i++) {
13099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        delete mInputSources.valueAt(i);
1312f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
1329cbbc837625cced18adabc57d71479044999155dEino-Ville Talvala    mInputSources.clear();
133f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
1342f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    for (size_t i = 0; i < mInputs.size(); i++) {
1352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mInputs.valueAt(i)->mEffects.clear();
1362f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        delete mInputs.valueAt(i);
1372f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
1382f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    mInputs.clear();
139a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
140a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov#ifdef USE_LEGACY_AUDIO_POLICY
141a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (mpAudioPolicy != NULL && mpAudioPolicyDev != NULL) {
1422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        mpAudioPolicyDev->destroy_audio_policy(mpAudioPolicyDev, mpAudioPolicy);
1432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
1442f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    if (mpAudioPolicyDev != NULL) {
1452f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        audio_policy_dev_close(mpAudioPolicyDev);
146aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    }
147c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh#else
148c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    delete mAudioPolicyManager;
149c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    delete mAudioPolicyClient;
150c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh#endif
151c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh}
152c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
153c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
154c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yehvoid AudioPolicyService::binderDied(const wp<IBinder>& who) {
155c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
156c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            IPCThreadState::self()->getCallingPid());
157c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh}
158c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
159aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peevstatic bool tryLock(Mutex& mutex)
1602f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala{
1612f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    bool locked = false;
162c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    for (int i = 0; i < kDumpLockRetries; ++i) {
163c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if (mutex.tryLock() == NO_ERROR) {
164c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            locked = true;
165c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            break;
1662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        }
167c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        usleep(kDumpLockSleepUs);
168c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    }
169aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    return locked;
170aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev}
171c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
172c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yehstatus_t AudioPolicyService::dumpInternals(int fd)
173c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh{
17492e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh    const size_t SIZE = 256;
17592e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh    char buffer[SIZE];
176c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    String8 result;
177c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
178c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh#ifdef USE_LEGACY_AUDIO_POLICY
179c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpAudioPolicy);
180c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh#else
181c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager);
18292e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh#endif
1832f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    result.append(buffer);
1842f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
1852f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    result.append(buffer);
1862823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
1872823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk    result.append(buffer);
188412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala
18992c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley    write(fd, result.string(), result.size());
19092c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley    return NO_ERROR;
1912823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk}
192f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala
193f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvalastatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused)
194f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala{
195f4db13db84c40299de4f9997f08d05259bdb8716Eino-Ville Talvala    if (!dumpAllowed()) {
19692c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley        dumpPermissionDenial(fd);
19792c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley    } else {
1982823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk        bool locked = tryLock(mLock);
19992c06fceabfa47906aaa7c747dcdd6376ccec358Christopher Wiley        if (!locked) {
200412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala            String8 result(kDeadlockedString);
201412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala            write(fd, result.string(), result.size());
202412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala        }
203412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala
204412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala        dumpInternals(fd);
205412fe56cd7cf7d73bc5d2bcc3f635bc650d18de9Eino-Ville Talvala        if (mAudioCommandThread != 0) {
2062823ce0ce6f9d508a07de20912c93cce9165027fRuben Brunk            mAudioCommandThread->dump(fd);
20765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
20865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mTonePlaybackThread != 0) {
20965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mTonePlaybackThread->dump(fd);
210d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk        }
211a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
21265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#ifdef USE_LEGACY_AUDIO_POLICY
21365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mpAudioPolicy) {
214aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev            mpAudioPolicy->dump(mpAudioPolicy, fd);
215aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        }
216aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev#else
217aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev        if (mAudioPolicyManager) {
218c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            mAudioPolicyManager->dump(fd);
219c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        }
220c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh#endif
221c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
222c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        if (locked) mLock.unlock();
223c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    }
224c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    return NO_ERROR;
225151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski}
226151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
227151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetskistatus_t AudioPolicyService::dumpPermissionDenial(int fd)
228151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski{
229151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    const size_t SIZE = 256;
230151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    char buffer[SIZE];
231151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    String8 result;
232151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    snprintf(buffer, SIZE, "Permission Denial: "
233151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            "can't dump AudioPolicyService from pid=%d, uid=%d\n",
234151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            IPCThreadState::self()->getCallingPid(),
235151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski            IPCThreadState::self()->getCallingUid());
236151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    result.append(buffer);
237151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    write(fd, result.string(), result.size());
238151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    return NO_ERROR;
239151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski}
240151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
241151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetskivoid AudioPolicyService::setPreProcessorEnabled(const InputDesc *inputDesc, bool enabled)
242151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski{
243151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    const Vector<sp<AudioEffect> > &fxVector = inputDesc->mEffects;
244151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    for (size_t i = 0; i < fxVector.size(); i++) {
245151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        fxVector.itemAt(i)->setEnabled(enabled);
246151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    }
247c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh}
248c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
249151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetskistatus_t AudioPolicyService::onTransact(
250151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
251151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski{
2526034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    return BnAudioPolicyService::onTransact(code, data, reply, flags);
253c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh}
2546034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski
2556034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski
2566034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski// -----------  AudioPolicyService::AudioCommandThread implementation ----------
2576034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski
2586034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi LiakhovetskiAudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
2596034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski                                                           const wp<AudioPolicyService>& service)
2606034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    : Thread(false), mName(name), mService(service)
2616034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski{
2626034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski    mpToneGenerator = NULL;
2636034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski}
264f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
265f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
266f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville TalvalaAudioPolicyService::AudioCommandThread::~AudioCommandThread()
267f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala{
268f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (!mAudioCommands.isEmpty()) {
269f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        release_wake_lock(mName.string());
270cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    }
271cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    for (size_t k=0; k < mAudioCommands.size(); k++) {
272cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        delete mAudioCommands[k]->mParam;
273cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        delete mAudioCommands[k];
27492e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh    }
275151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    mAudioCommands.clear();
27692e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh    delete mpToneGenerator;
277151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski}
278151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski
279151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetskivoid AudioPolicyService::AudioCommandThread::onFirstRef()
280151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski{
281151e3be07d27883ee590a4c4765077ffea16c954Guennadi Liakhovetski    run(mName.string(), ANDROID_PRIORITY_AUDIO);
28292e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh}
28392e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yeh
28492e3321e41e10f2e07a71f9512a6cadef7f40b64Yin-Chia Yehbool AudioPolicyService::AudioCommandThread::threadLoop()
285cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin{
286cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin    nsecs_t waitTime = INT64_MAX;
287cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin
288f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mLock.lock();
289cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    while (!exitPending())
290f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    {
291cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        while (!mAudioCommands.isEmpty()) {
292cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin            nsecs_t curTime = systemTime();
293cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin            // commands are sorted by increasing time stamp: execute them from index 0 and up
294cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin            if (mAudioCommands[0]->mTime <= curTime) {
295f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                AudioCommand *command = mAudioCommands[0];
296a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                mAudioCommands.removeAt(0);
297a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                mLastCommand = *command;
298c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
299c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                switch (command->mCommand) {
300c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                case START_TONE: {
301c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                    mLock.unlock();
302c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                    ToneData *data = (ToneData *)command->mParam;
303cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    ALOGV("AudioCommandThread() processing start tone %d on stream %d",
304cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin                            data->mType, data->mStream);
305cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    delete mpToneGenerator;
306cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
307cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin                    mpToneGenerator->startTone(data->mType);
308cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    delete data;
309cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    mLock.lock();
310cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin                    }break;
3118d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                case STOP_TONE: {
312cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    mLock.unlock();
3138d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                    ALOGV("AudioCommandThread() processing stop tone");
314cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    if (mpToneGenerator != NULL) {
3158d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                        mpToneGenerator->stopTone();
3168d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                        delete mpToneGenerator;
3178d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                        mpToneGenerator = NULL;
3188d942f9a5c5affcdc6f1138d4ce3bac4b7ee53d5Eino-Ville Talvala                    }
319cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    mLock.lock();
320d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    }break;
321d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                case SET_VOLUME: {
322cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    VolumeData *data = (VolumeData *)command->mParam;
323cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    ALOGV("AudioCommandThread() processing set volume stream %d, \
324cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                            volume %f, output %d", data->mStream, data->mVolume, data->mIO);
325cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    command->mStatus = AudioSystem::setStreamVolume(data->mStream,
326cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                                    data->mVolume,
327cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                                    data->mIO);
328cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    if (command->mWaitStatus) {
3296034bf5f21c57f66f3307d7934bc5c7616d2acf3Guennadi Liakhovetski                        command->mCond.signal();
330cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        command->mCond.waitRelative(mLock, kAudioCommandTimeout);
331f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    }
332a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                    delete data;
333a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                    }break;
334a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                case SET_PARAMETERS: {
335f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    ParametersData *data = (ParametersData *)command->mParam;
336cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
337cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin                            data->mKeyValuePairs.string(), data->mIO);
338cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin                    command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
339cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin                    if (command->mWaitStatus) {
34088da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                        command->mCond.signal();
341f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                        command->mCond.waitRelative(mLock, kAudioCommandTimeout);
3423068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                    }
3433068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                    delete data;
3443068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                    }break;
3453068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                case SET_VOICE_VOLUME: {
34688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                    VoiceVolumeData *data = (VoiceVolumeData *)command->mParam;
347f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    ALOGV("AudioCommandThread() processing set voice volume volume %f",
3483068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                            data->mVolume);
3493068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                    command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
3503068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                    if (command->mWaitStatus) {
351f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                        command->mCond.signal();
35288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                        command->mCond.waitRelative(mLock, kAudioCommandTimeout);
35388da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                    }
354f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                    delete data;
355f6463fc62a09b8aad8e811a9abbe9f4d9f2688f9Chien-Yu Chen                    }break;
35688da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                case STOP_OUTPUT: {
35788da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                    StopOutputData *data = (StopOutputData *)command->mParam;
35888da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                    ALOGV("AudioCommandThread() processing stop output %d",
3593068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                            data->mIO);
3603068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                    sp<AudioPolicyService> svc = mService.promote();
3613068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                    if (svc == 0) {
36288da526d97442c80731e01bfc94c6b47c4b0c3c7Chien-Yu Chen                        break;
3633068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                    }
364d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala                    mLock.unlock();
365d309fb9c8a2c4564d88fffba19c4e3688e4b862bEino-Ville Talvala                    svc->doStopOutput(data->mIO, data->mStream, data->mSession);
3663068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                    mLock.lock();
3673068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                    delete data;
3683068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen                    }break;
369cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                case RELEASE_OUTPUT: {
37099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    ReleaseOutputData *data = (ReleaseOutputData *)command->mParam;
371fe751bea0d3eedd6e817aebf4e457425b82e7117Chien-Yu Chen                    ALOGV("AudioCommandThread() processing release output %d",
37299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                            data->mIO);
37399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    sp<AudioPolicyService> svc = mService.promote();
37499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    if (svc == 0) {
37599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                        break;
37699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    }
37799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    mLock.unlock();
37899e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    svc->doReleaseOutput(data->mIO);
379f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    mLock.lock();
38099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    delete data;
38199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    }break;
382f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                default:
38399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                    ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
38499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                }
38599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                delete command;
38699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                waitTime = INT64_MAX;
38799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            } else {
388f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                waitTime = mAudioCommands[0]->mTime - curTime;
38999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk                break;
39099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            }
39199e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        }
39299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        // release delayed commands wake lock
39399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        if (mAudioCommands.isEmpty()) {
39499e69716215cd0665379bc90d708f2ea8689831dRuben Brunk            release_wake_lock(mName.string());
39599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        }
39699e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        ALOGV("AudioCommandThread() going to sleep");
39799e69716215cd0665379bc90d708f2ea8689831dRuben Brunk        mWaitWorkCV.waitRelative(mLock, waitTime);
398cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGV("AudioCommandThread() waking up");
399cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
400f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mLock.unlock();
401cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return false;
4023068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen}
4033068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
4043068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chenstatus_t AudioPolicyService::AudioCommandThread::dump(int fd)
405d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala{
406a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    const size_t SIZE = 256;
407aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    char buffer[SIZE];
408bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala    String8 result;
409bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala
410c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
411d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    result.append(buffer);
412bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala    write(fd, result.string(), result.size());
413d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
414d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    bool locked = tryLock(mLock);
415bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala    if (!locked) {
416d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        String8 result2(kCmdDeadlockedString);
417bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala        write(fd, result2.string(), result2.size());
418d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
419d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
420bad4358c83c7daaf9eeb8542c15eea4f473c884cEino-Ville Talvala    snprintf(buffer, SIZE, "- Commands:\n");
421d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    result = String8(buffer);
42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("   Command Time        Wait pParam\n");
42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t i = 0; i < mAudioCommands.size(); i++) {
424d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        mAudioCommands[i]->dump(buffer, SIZE);
425d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        result.append(buffer);
426a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala    }
427aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    result.append("  Last Command\n");
428aee727dd2f16bf299f738542b5e72fc72671f770Emilian Peev    mLastCommand.dump(buffer, SIZE);
4292f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    result.append(buffer);
430d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
431d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    write(fd, result.string(), result.size());
4328951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
4338951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (locked) mLock.unlock();
43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
435d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return NO_ERROR;
436d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala}
43765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type,
4392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        audio_stream_type_t stream)
440c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh{
441c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    AudioCommand *command = new AudioCommand();
442f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    command->mCommand = START_TONE;
443f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    ToneData *data = new ToneData();
444f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    data->mType = type;
445f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    data->mStream = stream;
446d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    command->mParam = data;
447f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    Mutex::Autolock _l(mLock);
4482f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    insertCommand_l(command);
44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mWaitWorkCV.signal();
451c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh}
452c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
453c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yehvoid AudioPolicyService::AudioCommandThread::stopToneCommand()
454c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh{
455c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    AudioCommand *command = new AudioCommand();
456cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    command->mCommand = STOP_TONE;
457c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    command->mParam = NULL;
458c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    Mutex::Autolock _l(mLock);
459c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    insertCommand_l(command);
460c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    ALOGV("AudioCommandThread() adding tone stop");
461c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    mWaitWorkCV.signal();
462c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh}
463c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
464cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstatus_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
465b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk                                                               float volume,
4662f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                                                               audio_io_handle_t output,
467f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                                                               int delayMs)
468a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala{
4692b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    status_t status = NO_ERROR;
4702b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
471d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    AudioCommand *command = new AudioCommand();
4722b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    command->mCommand = SET_VOLUME;
4732b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    VolumeData *data = new VolumeData();
4742f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    data->mStream = stream;
4752f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    data->mVolume = volume;
476d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    data->mIO = output;
477d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    command->mParam = data;
4782b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    Mutex::Autolock _l(mLock);
4792b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He    insertCommand_l(command, delayMs);
4802f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
481f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            stream, volume, output);
482f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    mWaitWorkCV.signal();
483f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    if (command->mWaitStatus) {
484f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        command->mCond.wait(mLock);
485f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        status =  command->mStatus;
486f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev        command->mCond.signal();
487f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    }
488f05e50eb06d3f70e50fa7f44c1fd32128033b49dZhijun He    return status;
489f05e50eb06d3f70e50fa7f44c1fd32128033b49dZhijun He}
4902b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He
4912b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun Hestatus_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle,
4922b59be89dc245b6e2475d9e8b0c5f2392370e71eZhijun He                                                                   const char *keyValuePairs,
493cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                                   int delayMs)
494cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk{
495cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    status_t status = NO_ERROR;
496cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
497cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    AudioCommand *command = new AudioCommand();
498cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    command->mCommand = SET_PARAMETERS;
499cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ParametersData *data = new ParametersData();
500cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    data->mIO = ioHandle;
501cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    data->mKeyValuePairs = String8(keyValuePairs);
502cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    command->mParam = data;
503cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    Mutex::Autolock _l(mLock);
504cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    insertCommand_l(command, delayMs);
505cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
506cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            keyValuePairs, ioHandle, delayMs);
507cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mWaitWorkCV.signal();
508d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (command->mWaitStatus) {
509d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        command->mCond.wait(mLock);
510d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        status =  command->mStatus;
511a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala        command->mCond.signal();
5122f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    }
5132f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    return status;
514d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala}
515d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk
5161e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvalastatus_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
5171e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala{
5181e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala    status_t status = NO_ERROR;
5191e74e241f5a4e0e763e27c888561405d013c9ca0Eino-Ville Talvala
520d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    AudioCommand *command = new AudioCommand();
521d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk    command->mCommand = SET_VOICE_VOLUME;
522d1176ef16677b6c94fb893edb6a864cdccc0b190Ruben Brunk    VoiceVolumeData *data = new VoiceVolumeData();
52371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    data->mVolume = volume;
52471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    command->mParam = data;
52571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    Mutex::Autolock _l(mLock);
52671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    insertCommand_l(command, delayMs);
52771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    ALOGV("AudioCommandThread() adding set voice volume volume %f", volume);
52871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    mWaitWorkCV.signal();
52971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    if (command->mWaitStatus) {
53071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        command->mCond.wait(mLock);
53171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        status =  command->mStatus;
53271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev        command->mCond.signal();
53371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    }
53471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev    return status;
53571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev}
53671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev
53771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peevvoid AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output,
53871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                                                               audio_stream_type_t stream,
5392f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                                                               int session)
540a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala{
541634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    AudioCommand *command = new AudioCommand();
5422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    command->mCommand = STOP_OUTPUT;
543634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    StopOutputData *data = new StopOutputData();
544f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    data->mIO = output;
545f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    data->mStream = stream;
546f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    data->mSession = session;
547f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    command->mParam = data;
548f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    Mutex::Autolock _l(mLock);
549f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    insertCommand_l(command);
550f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    ALOGV("AudioCommandThread() adding stop output %d", output);
551f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    mWaitWorkCV.signal();
552f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev}
553f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev
5546963d0ad7b621dcdaa74cbfed17c776121635146Eino-Ville Talvalavoid AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output)
555f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev{
5562f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    AudioCommand *command = new AudioCommand();
557f53f66edb3b06d1df5caf1fa806f7ed95305a4cfEmilian Peev    command->mCommand = RELEASE_OUTPUT;
558634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ReleaseOutputData *data = new ReleaseOutputData();
559634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    data->mIO = output;
560634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    command->mParam = data;
561d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    Mutex::Autolock _l(mLock);
562f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    insertCommand_l(command);
563f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    ALOGV("AudioCommandThread() adding release output %d", output);
564d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    mWaitWorkCV.signal();
565f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
566d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
567d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala// insertCommand_l() must be called with mLock held
568f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs)
569d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala{
570d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    ssize_t i;  // not size_t because i will count down to -1
571f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    Vector <AudioCommand *> removedCommands;
572d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    command->mTime = systemTime() + milliseconds(delayMs);
573d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
574d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    // acquire wake lock to make sure delayed commands are processed
575f67e23ef637d0b53a0d4bebb68c654234df3da94Eino-Ville Talvala    if (mAudioCommands.isEmpty()) {
576bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
577bfc9915f482520eb9676c6d2dbf7f1ac078d937dIgor Murashkin    }
578d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
5792f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // check same pending commands with later time stamps and eliminate them
580c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh    for (i = mAudioCommands.size()-1; i >= 0; i--) {
581c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        AudioCommand *command2 = mAudioCommands[i];
582cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
583b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk        if (command2->mTime <= command->mTime) break;
584cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (command2->mCommand != command->mCommand) continue;
585cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
586cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        switch (command->mCommand) {
587cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        case SET_PARAMETERS: {
588cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ParametersData *data = (ParametersData *)command->mParam;
589cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ParametersData *data2 = (ParametersData *)command2->mParam;
590cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (data->mIO != data2->mIO) break;
591c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            ALOGV("Comparing parameter command %s to new command %s",
592c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                    data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
593c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            AudioParameter param = AudioParameter(data->mKeyValuePairs);
594cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
595cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            for (size_t j = 0; j < param.size(); j++) {
596d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                String8 key;
5972f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                String8 value;
5982f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala                param.getAt(j, key, value);
599cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                for (size_t k = 0; k < param2.size(); k++) {
600cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    String8 key2;
601cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    String8 value2;
602cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    param2.getAt(k, key2, value2);
603cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    if (key2 == key) {
604cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        param2.remove(key2);
6054afbdecf8c6dc5ad04f6fa6c8712ce2c56a00c47Zhijun He                        ALOGV("Filtering out parameter %s", key2.string());
606cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                        break;
607cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    }
608c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh                }
609c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            }
610c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            // if all keys have been filtered out, remove the command.
611c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            // otherwise, update the key value pairs
612cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (param2.size() == 0) {
613d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                removedCommands.add(command2);
614d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            } else {
615d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                data2->mKeyValuePairs = param2.toString();
616cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            }
617b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk            command->mTime = command2->mTime;
618cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // force delayMs to non 0 so that code below does not request to wait for
619cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // command status as the command is now delayed
620cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            delayMs = 1;
621cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        } break;
622d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
6232f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala        case SET_VOLUME: {
6242f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala            VolumeData *data = (VolumeData *)command->mParam;
625b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk            VolumeData *data2 = (VolumeData *)command2->mParam;
626cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (data->mIO != data2->mIO) break;
627cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (data->mStream != data2->mStream) break;
628cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGV("Filtering out volume command on output %d for stream %d",
629cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                    data->mIO, data->mStream);
630cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            removedCommands.add(command2);
631cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            command->mTime = command2->mTime;
632cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // force delayMs to non 0 so that code below does not request to wait for
633c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            // command status as the command is now delayed
634c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh            delayMs = 1;
635c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh        } break;
636cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        case START_TONE:
637cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        case STOP_TONE:
638cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        default:
639cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            break;
640cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
641d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    }
6422f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala
6432f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    // remove filtered commands
644b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk    for (size_t j = 0; j < removedCommands.size(); j++) {
645b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk        // removed commands always have time stamps greater than current command
646d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
647cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            if (mAudioCommands[k] == removedCommands[j]) {
648cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
6496267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk                // for commands that are not filtered,
6506267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk                // command->mParam is deleted in threadLoop
6516267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk                delete mAudioCommands[k]->mParam;
6526267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk                delete mAudioCommands[k];
6536267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk                mAudioCommands.removeAt(k);
6546267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk                break;
6556267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            }
6566267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
6576267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    }
6586267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    removedCommands.clear();
6596267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk
6606267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    // wait for status only if delay is 0
6616267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk    if (delayMs == 0) {
6626267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        command->mWaitStatus = true;
663f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    } else {
664f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        command->mWaitStatus = false;
665f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
666f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
667f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    // insert command at the right place according to its time stamp
668f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    ALOGV("inserting command: %d at index %d, num commands %d",
669f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            command->mCommand, (int)i+1, mAudioCommands.size());
670f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mAudioCommands.insertAt(command, i + 1);
671f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
672f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
673f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid AudioPolicyService::AudioCommandThread::exit()
674f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala{
675f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    ALOGV("AudioCommandThread::exit");
676f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    {
677f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        AutoMutex _l(mLock);
678f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        requestExit();
679f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        mWaitWorkCV.signal();
680f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
681f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    requestExitAndWait();
682f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
683f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
684f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
685f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala{
686f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
687f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mCommand,
688f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            (int)ns2s(mTime),
689f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            (int)ns2ms(mTime)%1000,
690f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mWaitStatus,
691f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mParam);
692f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
693f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
694f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala/******* helpers for the service_ops callbacks defined below *********/
695f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
696f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                                       const char *keyValuePairs,
697f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                                       int delayMs)
698f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala{
699f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs,
700f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                                           delayMs);
701f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
702f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
703f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalaint AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
704f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                                        float volume,
705f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                                        audio_io_handle_t output,
706f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                                        int delayMs)
707f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala{
708f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    return (int)mAudioCommandThread->volumeCommand(stream, volume,
709f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                                                   output, delayMs);
710f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
711f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
712f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalaint AudioPolicyService::startTone(audio_policy_tone_t tone,
713f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                                  audio_stream_type_t stream)
714f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala{
715f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) {
716f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        ALOGE("startTone: illegal tone requested (%d)", tone);
717f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
718f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (stream != AUDIO_STREAM_VOICE_CALL) {
719f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        ALOGE("startTone: illegal stream (%d) requested for tone %d", stream,
720f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            tone);
721f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
722f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING,
723d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                                          AUDIO_STREAM_VOICE_CALL);
724cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return 0;
725b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk}
72698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen
727cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint AudioPolicyService::stopTone()
728d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala{
729cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    mTonePlaybackThread->stopToneCommand();
730d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return 0;
731c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh}
732c3e9d6f704f7bf9e94c8447aa2f0f21e750c08beYin-Chia Yeh
733d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalaint AudioPolicyService::setVoiceVolume(float volume, int delayMs)
734d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala{
735d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
736d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala}
737d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
738b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk// ----------------------------------------------------------------------------
739d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala// Audio pre-processing configuration
740b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk// ----------------------------------------------------------------------------
741b2119af7f4ced0ecfefd4c7388f86b4e3a3ea7d8Ruben Brunk
742d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala/*static*/ const char * const AudioPolicyService::kInputSourceNames[AUDIO_SOURCE_CNT -1] = {
74365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    MIC_SRC_TAG,
74465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    VOICE_UL_SRC_TAG,
74565d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    VOICE_DL_SRC_TAG,
74665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    VOICE_CALL_SRC_TAG,
74765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    CAMCORDER_SRC_TAG,
748d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    VOICE_REC_SRC_TAG,
74965d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    VOICE_COMM_SRC_TAG
75065d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin};
75165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
752d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala// returns the audio_source_t enum corresponding to the input source name or
75365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin// AUDIO_SOURCE_CNT is no match found
75465d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkinaudio_source_t AudioPolicyService::inputSourceNameToEnum(const char *name)
755cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk{
75665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    int i;
757cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) {
758cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) {
759cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGV("inputSourceNameToEnum found source %s %d", name, i);
760cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            break;
761cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
762cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
763cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return (audio_source_t)i;
764d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala}
765d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
76665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkinsize_t AudioPolicyService::growParamSize(char *param,
767cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                         size_t size,
768cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                         size_t *curSize,
769cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                         size_t *totSize)
770d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala{
77165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int)
772cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    size_t pos = ((*curSize - 1 ) / size + 1) * size;
77365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin
774cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (pos + size > *totSize) {
775cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        while (pos + size > *totSize) {
776cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            *totSize += ((*totSize + 7) / 8) * 4;
777d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        }
778cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        param = (char *)realloc(param, *totSize);
779cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
780cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    *curSize = pos + size;
78165d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin    return pos;
782cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
783cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
784cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunksize_t AudioPolicyService::readParamValue(cnode *node,
785cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                          char *param,
786cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                          size_t *curSize,
787cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                          size_t *totSize)
788cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk{
789d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) {
790d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        size_t pos = growParamSize(param, sizeof(short), curSize, totSize);
791cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        *(short *)((char *)param + pos) = (short)atoi(node->value);
792cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGV("readParamValue() reading short %d", *(short *)((char *)param + pos));
793cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return sizeof(short);
794cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) {
795d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        size_t pos = growParamSize(param, sizeof(int), curSize, totSize);
79665d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        *(int *)((char *)param + pos) = atoi(node->value);
79765d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        ALOGV("readParamValue() reading int %d", *(int *)((char *)param + pos));
79865d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        return sizeof(int);
799cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) {
800cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        size_t pos = growParamSize(param, sizeof(float), curSize, totSize);
801d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        *(float *)((char *)param + pos) = (float)atof(node->value);
80265d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        ALOGV("readParamValue() reading float %f",*(float *)((char *)param + pos));
80365d14b9825311f9d1847cf282bd0419e71bac666Igor Murashkin        return sizeof(float);
80498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) {
80598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        size_t pos = growParamSize(param, sizeof(bool), curSize, totSize);
80698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        if (strncmp(node->value, "false", strlen("false") + 1) == 0) {
807af9d030e075e659e9f50fdd143aa83459a7795e2Eino-Ville Talvala            *(bool *)((char *)param + pos) = false;
80898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        } else {
809af9d030e075e659e9f50fdd143aa83459a7795e2Eino-Ville Talvala            *(bool *)((char *)param + pos) = true;
81098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        }
81198a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        ALOGV("readParamValue() reading bool %s",*(bool *)((char *)param + pos) ? "true" : "false");
81298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        return sizeof(bool);
81398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) {
81498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        size_t len = strnlen(node->value, EFFECT_STRING_LEN_MAX);
81598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        if (*curSize + len + 1 > *totSize) {
816d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            *totSize = *curSize + len + 1;
81718df60e094edbaa08cbecd25b0398643b8a0f29aChien-Yu Chen            param = (char *)realloc(param, *totSize);
81818df60e094edbaa08cbecd25b0398643b8a0f29aChien-Yu Chen        }
8195861a9a98c641261c4807c976c750e4611b3a57dTyler Luu        strncpy(param + *curSize, node->value, len);
8209c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo        *curSize += len;
8219c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo        param[*curSize] = '\0';
8229c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo        ALOGV("readParamValue() reading string %s", param + *curSize - len);
8239c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo        return len;
8249c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    }
8259c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    ALOGW("readParamValue() unknown param type %s", node->name);
8267939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen    return 0;
8277939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen}
8280492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala
829ce761d1fef4da2a4dec3eb538d103fcde1971dbaChristopher Wileyeffect_param_t *AudioPolicyService::loadEffectParameter(cnode *root)
830ce761d1fef4da2a4dec3eb538d103fcde1971dbaChristopher Wiley{
8319c2a2c26c0d70de97f51063b06a5efc79b327eedAlex Deymo    cnode *param;
832ce761d1fef4da2a4dec3eb538d103fcde1971dbaChristopher Wiley    cnode *value;
8330492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    size_t curSize = sizeof(effect_param_t);
8340492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int);
8352f09bac6632a5ee27ee14baa2aa1367f16b5b013Eino-Ville Talvala    effect_param_t *fx_param = (effect_param_t *)malloc(totSize);
836cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
837cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    param = config_find(root, PARAM_TAG);
8380492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    value = config_find(root, VALUE_TAG);
8390492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    if (param == NULL && value == NULL) {
8408951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        // try to parse simple parameter form {int int}
8418951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        param = root->first_child;
842cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (param != NULL) {
843cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            // Note: that a pair of random strings is read as 0 0
844cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            int *ptr = (int *)fx_param->data;
8450492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            int *ptr2 = (int *)((char *)param + sizeof(effect_param_t));
8460492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            ALOGW("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2);
84765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            *ptr++ = atoi(param->name);
84865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            *ptr = atoi(param->value);
8490492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            fx_param->psize = sizeof(int);
8500492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            fx_param->vsize = sizeof(int);
8510492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala            return fx_param;
8520492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        }
8530492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    }
8540492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    if (param == NULL || value == NULL) {
8550492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        ALOGW("loadEffectParameter() invalid parameter description %s", root->name);
8560492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        goto error;
8570492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    }
8580492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala
8590492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    fx_param->psize = 0;
8600492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    param = param->first_child;
8610492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala    while (param) {
8620039bcf0c4f10b92917c26df70c7847f1ab0b51eChristopher Wiley        ALOGV("loadEffectParameter() reading param of type %s", param->name);
8630039bcf0c4f10b92917c26df70c7847f1ab0b51eChristopher Wiley        size_t size = readParamValue(param, (char *)fx_param, &curSize, &totSize);
8640492686c4703b3ddbff52d047ef226b973a3388aEino-Ville Talvala        if (size == 0) {
8657939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen            goto error;
8667939aee8c1688bc8647c5bceb0d47a4e790ff27dChien-Yu Chen        }
8670039bcf0c4f10b92917c26df70c7847f1ab0b51eChristopher Wiley        fx_param->psize += size;
86898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        param = param->next;
8695861a9a98c641261c4807c976c750e4611b3a57dTyler Luu    }
87098a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen
871ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    // align start of value field on 32 bit boundary
87298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int);
87398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen
87498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    fx_param->vsize = 0;
87598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    value = value->first_child;
876d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    while (value) {
877d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGV("loadEffectParameter() reading value of type %s", value->name);
878d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        size_t size = readParamValue(value, (char *)fx_param, &curSize, &totSize);
879d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        if (size == 0) {
880d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            goto error;
88198a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        }
88298a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        fx_param->vsize += size;
88398a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        value = value->next;
88498a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    }
88598a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen
88698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    return fx_param;
88798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen
88898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chenerror:
889d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    free(fx_param);
890d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return NULL;
891d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala}
892d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
893d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalavoid AudioPolicyService::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params)
894ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala{
89565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cnode *node = root->first_child;
89698a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen    while (node) {
89798a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        ALOGV("loadEffectParameters() loading param %s", node->name);
89898a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        effect_param_t *param = loadEffectParameter(node);
89998a668f6ea51e4d894d2ebb61a0e18287fb14008Chien-Yu Chen        if (param == NULL) {
900d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            node = node->next;
901d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            continue;
902d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        }
903ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        params.add(param);
90465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        node = node->next;
905a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    }
906a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov}
907a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov
908a453d0d278ee916bf68c98093fcfd9fa924ca454Svet GanovAudioPolicyService::InputSourceDesc *AudioPolicyService::loadInputSource(
909a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                                                            cnode *root,
910a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov                                                            const Vector <EffectDesc *>& effects)
911a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov{
912a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    cnode *node = root->first_child;
913a453d0d278ee916bf68c98093fcfd9fa924ca454Svet Ganov    if (node == NULL) {
9144f3d6203c71f9e76fbd2964ad54a81b7036f7e17Chien-Yu Chen        ALOGW("loadInputSource() empty element %s", root->name);
9154f3d6203c71f9e76fbd2964ad54a81b7036f7e17Chien-Yu Chen        return NULL;
91618df60e094edbaa08cbecd25b0398643b8a0f29aChien-Yu Chen    }
9174f3d6203c71f9e76fbd2964ad54a81b7036f7e17Chien-Yu Chen    InputSourceDesc *source = new InputSourceDesc();
91865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (node) {
9196267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        size_t i;
920a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li        for (i = 0; i < effects.size(); i++) {
921a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk            if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) {
922a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk                ALOGV("loadInputSource() found effect %s in list", node->name);
9236267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk                break;
9246267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk            }
9256267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        }
9266267b539d0d1ee7118aafd976d75cb8db397bc24Ruben Brunk        if (i == effects.size()) {
927d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGV("loadInputSource() effect %s not in list", node->name);
928d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            node = node->next;
929d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            continue;
93036597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        }
93136597b241c59eba7e55d5150092947a748c5e9cbRuben Brunk        EffectDesc *effect = new EffectDesc(*effects[i]);   // deep copy
932d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        loadEffectParameters(node, effect->mParams);
933cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGV("loadInputSource() adding effect %s uuid %08x", effect->mName, effect->mUuid.timeLow);
934cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        source->mEffects.add(effect);
935cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        node = node->next;
936cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
937cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    if (source->mEffects.size() == 0) {
938cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGW("loadInputSource() no valid effects found in source %s", root->name);
939cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        delete source;
940cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return NULL;
941cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
942cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return source;
943cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
944f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
945f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalastatus_t AudioPolicyService::loadInputSources(cnode *root, const Vector <EffectDesc *>& effects)
946cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk{
947cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    cnode *node = config_find(root, PREPROCESSING_TAG);
9480f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk    if (node == NULL) {
949f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        return -ENOENT;
950cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
951cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    node = node->first_child;
9520f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk    while (node) {
953cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        audio_source_t source = inputSourceNameToEnum(node->name);
954cba2c163555cd329f49d40658ea3ee902e94dda3Igor Murashkin        if (source == AUDIO_SOURCE_CNT) {
955cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            ALOGW("loadInputSources() invalid input source %s", node->name);
956e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin            node = node->next;
957e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin            continue;
958cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
959cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGV("loadInputSources() loading input source %s", node->name);
960e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin        InputSourceDesc *desc = loadInputSource(node, effects);
961cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        if (desc == NULL) {
962cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            node = node->next;
963cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            continue;
964cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
965cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        mInputSources.add(source, desc);
966cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        node = node->next;
967cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
968cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return NO_ERROR;
969cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
970cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
971cc776718c0be7c31fe5ab4fc1446d377be60369fRuben BrunkAudioPolicyService::EffectDesc *AudioPolicyService::loadEffect(cnode *root)
972cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk{
9732fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    cnode *node = config_find(root, UUID_TAG);
974e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin    if (node == NULL) {
975cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return NULL;
976cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
977cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    effect_uuid_t uuid;
97824901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) {
97924901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala        ALOGW("loadEffect() invalid uuid %s", node->value);
98024901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala        return NULL;
98124901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    }
98224901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    return new EffectDesc(root->name, uuid);
98324901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala}
98424901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala
98524901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvalastatus_t AudioPolicyService::loadEffects(cnode *root, Vector <EffectDesc *>& effects)
98624901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala{
98724901c86e10a0923fe10f5e9bce5e6dba061a289Eino-Ville Talvala    cnode *node = config_find(root, EFFECTS_TAG);
988e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin    if (node == NULL) {
989e6800cea0678dbc0bf697b44c3e4548b0253085cIgor Murashkin        return -ENOENT;
990cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
991cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    node = node->first_child;
992a858ea0495c887621a2fd9c0afc13780deccb597Igor Murashkin    while (node) {
993cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        ALOGV("loadEffects() loading effect %s", node->name);
994cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        EffectDesc *effect = loadEffect(node);
995a84bbe6b59721b1b963d65d270aa98d6513bbb78Eino-Ville Talvala        if (effect == NULL) {
996cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk            node = node->next;
9974f9576bf48c5909782c12490e8a9faa974ae68d6Ruben Brunk            continue;
998cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        }
999cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        effects.add(effect);
1000cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        node = node->next;
1001cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
1002cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    return NO_ERROR;
1003cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}
1004cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1005cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkstatus_t AudioPolicyService::loadPreProcessorConfig(const char *path)
1006cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk{
1007cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    cnode *root;
10080bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk    char *data;
10090bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk
10100bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk    data = (char *)load_file(path, NULL);
10110bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk    if (data == NULL) {
1012cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        return -ENODEV;
10130bbf8b213ad96051357e3ad6d6d2808bfa31a59aRuben Brunk    }
1014cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    root = config_node("", "");
1015cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    config_load(root, data);
1016cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1017cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    Vector <EffectDesc *> effects;
1018cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    loadEffects(root, effects);
1019cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    loadInputSources(root, effects);
10203068d73c6c7e1f44523b1466b903a9c82408b258Chien-Yu Chen
1021cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // delete effects to fix memory leak.
1022cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // as effects is local var and valgrind would treat this as memory leak
1023cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    // and although it only did in mediaserver init, but free it in case mediaserver reboot
1024cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    size_t i;
10258131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev    for (i = 0; i < effects.size(); i++) {
10268131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev      delete effects[i];
1027cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    }
10288131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev
10298131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev    config_free(root);
10308131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev    free(root);
10318131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev    free(data);
10328131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev
10338131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev    return NO_ERROR;
10348131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev}
10358131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev
10368131a26957de26f15c6b41a64eb299ff61888e88Emilian Peevextern "C" {
1037cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkaudio_module_handle_t aps_load_hw_module(void *service __unused,
1038cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                             const char *name);
10398131a26957de26f15c6b41a64eb299ff61888e88Emilian Peevaudio_io_handle_t aps_open_output(void *service __unused,
1040cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                         audio_devices_t *pDevices,
10418131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                                         uint32_t *pSamplingRate,
10428131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                                         audio_format_t *pFormat,
1043cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                         audio_channel_mask_t *pChannelMask,
1044cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                         uint32_t *pLatencyMs,
1045cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                         audio_output_flags_t flags);
1046cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1047cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkaudio_io_handle_t aps_open_output_on_module(void *service __unused,
1048cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                   audio_module_handle_t module,
1049cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                   audio_devices_t *pDevices,
1050cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                   uint32_t *pSamplingRate,
1051d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                                                   audio_format_t *pFormat,
1052b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He                                                   audio_channel_mask_t *pChannelMask,
1053b10cdadf0fb945e23ca77008d4af76584bd0e39aZhijun He                                                   uint32_t *pLatencyMs,
1054cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                   audio_output_flags_t flags,
1055cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                   const audio_offload_info_t *offloadInfo);
1056cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkaudio_io_handle_t aps_open_dup_output(void *service __unused,
1057cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                 audio_io_handle_t output1,
1058cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                 audio_io_handle_t output2);
10598131a26957de26f15c6b41a64eb299ff61888e88Emilian Peevint aps_close_output(void *service __unused, audio_io_handle_t output);
10608131a26957de26f15c6b41a64eb299ff61888e88Emilian Peevint aps_suspend_output(void *service __unused, audio_io_handle_t output);
10618131a26957de26f15c6b41a64eb299ff61888e88Emilian Peevint aps_restore_output(void *service __unused, audio_io_handle_t output);
1062cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkaudio_io_handle_t aps_open_input(void *service __unused,
1063cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                        audio_devices_t *pDevices,
1064cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                        uint32_t *pSamplingRate,
1065cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                        audio_format_t *pFormat,
1066cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                        audio_channel_mask_t *pChannelMask,
1067cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                        audio_in_acoustics_t acoustics __unused);
1068cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkaudio_io_handle_t aps_open_input_on_module(void *service __unused,
1069cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                  audio_module_handle_t module,
1070cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                  audio_devices_t *pDevices,
1071cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                  uint32_t *pSamplingRate,
1072cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                  audio_format_t *pFormat,
1073cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                                  audio_channel_mask_t *pChannelMask);
1074cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint aps_close_input(void *service __unused, audio_io_handle_t input);
1075cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint aps_invalidate_stream(void *service __unused, audio_stream_type_t stream);
1076cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint aps_move_effects(void *service __unused, int session,
1077cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                audio_io_handle_t src_output,
10788131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                                audio_io_handle_t dst_output);
1079cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkchar * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle,
10808131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                                     const char *keys);
10818131a26957de26f15c6b41a64eb299ff61888e88Emilian Peevvoid aps_set_parameters(void *service, audio_io_handle_t io_handle,
1082cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                   const char *kv_pairs, int delay_ms);
1083cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunkint aps_set_stream_volume(void *service, audio_stream_type_t stream,
1084cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk                                     float volume, audio_io_handle_t output,
10858131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                                     int delay_ms);
10868131a26957de26f15c6b41a64eb299ff61888e88Emilian Peevint aps_start_tone(void *service, audio_policy_tone_t tone,
10878131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev                              audio_stream_type_t stream);
10888131a26957de26f15c6b41a64eb299ff61888e88Emilian Peevint aps_stop_tone(void *service);
10898131a26957de26f15c6b41a64eb299ff61888e88Emilian Peevint aps_set_voice_volume(void *service, float volume, int delay_ms);
1090022f0cb0c6f135edde4ebe84859c685933ee895eEino-Ville Talvala};
10918131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev
1092022f0cb0c6f135edde4ebe84859c685933ee895eEino-Ville Talvalanamespace {
10938131a26957de26f15c6b41a64eb299ff61888e88Emilian Peev    struct audio_policy_service_ops aps_ops = {
1094cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .open_output           = aps_open_output,
1095cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .open_duplicate_output = aps_open_dup_output,
1096cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .close_output          = aps_close_output,
1097a8ca9157d21510fbd474bd31748f4fe0d4635dd7Ruben Brunk        .suspend_output        = aps_suspend_output,
1098cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .restore_output        = aps_restore_output,
1099cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .open_input            = aps_open_input,
1100cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .close_input           = aps_close_input,
1101cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .set_stream_volume     = aps_set_stream_volume,
1102cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .invalidate_stream     = aps_invalidate_stream,
1103cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .set_parameters        = aps_set_parameters,
1104cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .get_parameters        = aps_get_parameters,
1105cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .start_tone            = aps_start_tone,
1106cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .stop_tone             = aps_stop_tone,
1107cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .set_voice_volume      = aps_set_voice_volume,
1108cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .move_effects          = aps_move_effects,
1109cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .load_hw_module        = aps_load_hw_module,
1110cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .open_output_on_module = aps_open_output_on_module,
1111cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk        .open_input_on_module  = aps_open_input_on_module,
1112cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk    };
1113cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}; // namespace <unnamed>
1114cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk
1115cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk}; // namespace android
1116cc776718c0be7c31fe5ab4fc1446d377be60369fRuben Brunk