HwModule.cpp revision 98cc191247388132b6fd8a4ecd07abd6e4c5a0ed
124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown/*
224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Copyright (C) 2015 The Android Open Source Project
324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown *
424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * you may not use this file except in compliance with the License.
624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * You may obtain a copy of the License at
724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown *
824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown *
1024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Unless required by applicable law or agreed to in writing, software
1124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
1224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * See the License for the specific language governing permissions and
1424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * limitations under the License.
1524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */
1624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
1724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown#define LOG_TAG "APM::HwModule"
1824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown//#define LOG_NDEBUG 0
1924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
2024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown#include "HwModule.h"
2124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown#include "IOProfile.h"
22f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake#include "AudioGain.h"
2324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown#include "ConfigParsingUtils.h"
2424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown#include "audio_policy_conf.h"
25f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake#include <hardware/audio.h>
26f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake
27f0e4dea75691d2fd1256508136ecce88bef6067bIan Lakenamespace android {
2824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
2924fa6c0dd42df057729e1a258388183f94da7f82Jeff BrownHwModule::HwModule(const char *name)
3024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)),
3124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown      mHalVersion(AUDIO_DEVICE_API_VERSION_MIN), mHandle(0)
3224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown{
3324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown}
3424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
3524fa6c0dd42df057729e1a258388183f94da7f82Jeff BrownHwModule::~HwModule()
3624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown{
3724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    for (size_t i = 0; i < mOutputProfiles.size(); i++) {
3824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        mOutputProfiles[i]->mSupportedDevices.clear();
3924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
40f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    for (size_t i = 0; i < mInputProfiles.size(); i++) {
41f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake        mInputProfiles[i]->mSupportedDevices.clear();
42f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    }
43f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    free((void *)mName);
44f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake}
45f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake
46f0e4dea75691d2fd1256508136ecce88bef6067bIan Lakestatus_t HwModule::loadInput(cnode *root)
47f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake{
48f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    cnode *node = root->first_child;
49f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake
50f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SINK, this);
51f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake
52f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    while (node) {
53f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake        if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
54f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake            profile->loadSamplingRates((char *)node->value);
5524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        } else if (strcmp(node->name, FORMATS_TAG) == 0) {
5624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            profile->loadFormats((char *)node->value);
5724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
5824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            profile->loadInChannels((char *)node->value);
5924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        } else if (strcmp(node->name, DEVICES_TAG) == 0) {
6024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            profile->mSupportedDevices.loadDevicesFromName((char *)node->value,
6124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown                                                           mDeclaredDevices);
6224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        } else if (strcmp(node->name, FLAGS_TAG) == 0) {
6324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            profile->mFlags = ConfigParsingUtils::parseInputFlagNames((char *)node->value);
6424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        } else if (strcmp(node->name, GAINS_TAG) == 0) {
6524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            profile->loadGains(node);
6624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
6724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        node = node->next;
6824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
6924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    ALOGW_IF(profile->mSupportedDevices.isEmpty(),
7024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            "loadInput() invalid supported devices");
7124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    ALOGW_IF(profile->mChannelMasks.size() == 0,
7224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            "loadInput() invalid supported channel masks");
7324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    ALOGW_IF(profile->mSamplingRates.size() == 0,
7424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            "loadInput() invalid supported sampling rates");
7524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    ALOGW_IF(profile->mFormats.size() == 0,
7624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            "loadInput() invalid supported formats");
7724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    if (!profile->mSupportedDevices.isEmpty() &&
7824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            (profile->mChannelMasks.size() != 0) &&
7924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            (profile->mSamplingRates.size() != 0) &&
8024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            (profile->mFormats.size() != 0)) {
8124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
8224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        ALOGV("loadInput() adding input Supported Devices %04x",
8324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown              profile->mSupportedDevices.types());
8424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
8524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        mInputProfiles.add(profile);
8624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return NO_ERROR;
8724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    } else {
8824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return BAD_VALUE;
8924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
9024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown}
9124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
9224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownstatus_t HwModule::loadOutput(cnode *root)
9324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown{
9424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    cnode *node = root->first_child;
9524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
9624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SOURCE, this);
9724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
9824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    while (node) {
99f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake        if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
10024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            profile->loadSamplingRates((char *)node->value);
10124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        } else if (strcmp(node->name, FORMATS_TAG) == 0) {
10224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            profile->loadFormats((char *)node->value);
10324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
10424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            profile->loadOutChannels((char *)node->value);
10524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        } else if (strcmp(node->name, DEVICES_TAG) == 0) {
10624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            profile->mSupportedDevices.loadDevicesFromName((char *)node->value,
10724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown                                                           mDeclaredDevices);
10824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        } else if (strcmp(node->name, FLAGS_TAG) == 0) {
10924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            profile->mFlags = ConfigParsingUtils::parseOutputFlagNames((char *)node->value);
11024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        } else if (strcmp(node->name, GAINS_TAG) == 0) {
11124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            profile->loadGains(node);
11224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
11324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        node = node->next;
11424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
11524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    ALOGW_IF(profile->mSupportedDevices.isEmpty(),
11624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            "loadOutput() invalid supported devices");
11724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    ALOGW_IF(profile->mChannelMasks.size() == 0,
11824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            "loadOutput() invalid supported channel masks");
11924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    ALOGW_IF(profile->mSamplingRates.size() == 0,
12024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            "loadOutput() invalid supported sampling rates");
12124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    ALOGW_IF(profile->mFormats.size() == 0,
12224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            "loadOutput() invalid supported formats");
12324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    if (!profile->mSupportedDevices.isEmpty() &&
12424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            (profile->mChannelMasks.size() != 0) &&
12524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            (profile->mSamplingRates.size() != 0) &&
12624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            (profile->mFormats.size() != 0)) {
12724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
12824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        ALOGV("loadOutput() adding output Supported Devices %04x, mFlags %04x",
12924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown              profile->mSupportedDevices.types(), profile->mFlags);
13024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
13124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        mOutputProfiles.add(profile);
13224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return NO_ERROR;
13324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    } else {
13424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return BAD_VALUE;
13524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
13624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown}
13724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
13824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownstatus_t HwModule::loadDevice(cnode *root)
13924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown{
14024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    cnode *node = root->first_child;
14124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
14224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    audio_devices_t type = AUDIO_DEVICE_NONE;
14324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    while (node) {
14424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        if (strcmp(node->name, DEVICE_TYPE) == 0) {
14524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            type = ConfigParsingUtils::parseDeviceNames((char *)node->value);
14624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            break;
14724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
148f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake        node = node->next;
14924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
15024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    if (type == AUDIO_DEVICE_NONE ||
15124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            (!audio_is_input_device(type) && !audio_is_output_device(type))) {
15224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        ALOGW("loadDevice() bad type %08x", type);
15324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        return BAD_VALUE;
15424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
15524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    sp<DeviceDescriptor> deviceDesc = new DeviceDescriptor(String8(root->name), type);
15624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    deviceDesc->mModule = this;
15724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
15824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    node = root->first_child;
15924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    while (node) {
16024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        if (strcmp(node->name, DEVICE_ADDRESS) == 0) {
16124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            deviceDesc->mAddress = String8((char *)node->value);
16224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
16324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            if (audio_is_input_device(type)) {
16424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown                deviceDesc->loadInChannels((char *)node->value);
16524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            } else {
16624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown                deviceDesc->loadOutChannels((char *)node->value);
16724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            }
16824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        } else if (strcmp(node->name, GAINS_TAG) == 0) {
16924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            deviceDesc->loadGains(node);
17024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
17124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        node = node->next;
17224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
17324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
17424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    ALOGV("loadDevice() adding device name %s type %08x address %s",
17524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown          deviceDesc->mName.string(), type, deviceDesc->mAddress.string());
17624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
17724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    mDeclaredDevices.add(deviceDesc);
17824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
17924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    return NO_ERROR;
18024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown}
18124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
18224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownstatus_t HwModule::addOutputProfile(String8 name, const audio_config_t *config,
18324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown                                                  audio_devices_t device, String8 address)
18424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown{
18524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SOURCE, this);
18624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
18724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    profile->mSamplingRates.add(config->sample_rate);
18824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    profile->mChannelMasks.add(config->channel_mask);
18924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    profile->mFormats.add(config->format);
19024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
19124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(name, device);
19224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    devDesc->mAddress = address;
19324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    profile->mSupportedDevices.add(devDesc);
19424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
19524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    mOutputProfiles.add(profile);
196f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake
197f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake    return NO_ERROR;
19824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown}
19924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
20024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownstatus_t HwModule::removeOutputProfile(String8 name)
20124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown{
20224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    for (size_t i = 0; i < mOutputProfiles.size(); i++) {
20324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        if (mOutputProfiles[i]->mName == name) {
20424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mOutputProfiles.removeAt(i);
20524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            break;
20624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
20724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
20824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
20924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    return NO_ERROR;
21024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown}
21124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
21224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownstatus_t HwModule::addInputProfile(String8 name, const audio_config_t *config,
21324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown                                                  audio_devices_t device, String8 address)
21424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown{
21524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    sp<IOProfile> profile = new IOProfile(name, AUDIO_PORT_ROLE_SINK, this);
21624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
21724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    profile->mSamplingRates.add(config->sample_rate);
21824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    profile->mChannelMasks.add(config->channel_mask);
21924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    profile->mFormats.add(config->format);
22024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
22124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(name, device);
22224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    devDesc->mAddress = address;
22324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    profile->mSupportedDevices.add(devDesc);
22424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
22524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    ALOGV("addInputProfile() name %s rate %d mask 0x08", name.string(), config->sample_rate, config->channel_mask);
22624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
22724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    mInputProfiles.add(profile);
22824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
22924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    return NO_ERROR;
23024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown}
23124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
23224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownstatus_t HwModule::removeInputProfile(String8 name)
23324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown{
23424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    for (size_t i = 0; i < mInputProfiles.size(); i++) {
23524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        if (mInputProfiles[i]->mName == name) {
23624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mInputProfiles.removeAt(i);
23724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            break;
23824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
23924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
24024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
24124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    return NO_ERROR;
24224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown}
24324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
24424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
24524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownvoid HwModule::dump(int fd)
24624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown{
24724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    const size_t SIZE = 256;
24824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    char buffer[SIZE];
24924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    String8 result;
250f0e4dea75691d2fd1256508136ecce88bef6067bIan Lake
25124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    snprintf(buffer, SIZE, "  - name: %s\n", mName);
25224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    result.append(buffer);
25324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    snprintf(buffer, SIZE, "  - handle: %d\n", mHandle);
25424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    result.append(buffer);
25524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    snprintf(buffer, SIZE, "  - version: %u.%u\n", mHalVersion >> 8, mHalVersion & 0xFF);
25624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    result.append(buffer);
25724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    write(fd, result.string(), result.size());
25824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    if (mOutputProfiles.size()) {
25924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        write(fd, "  - outputs:\n", strlen("  - outputs:\n"));
26024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        for (size_t i = 0; i < mOutputProfiles.size(); i++) {
26124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            snprintf(buffer, SIZE, "    output %zu:\n", i);
26224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            write(fd, buffer, strlen(buffer));
26324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mOutputProfiles[i]->dump(fd);
26424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
26524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
26624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    if (mInputProfiles.size()) {
26724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        write(fd, "  - inputs:\n", strlen("  - inputs:\n"));
26824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        for (size_t i = 0; i < mInputProfiles.size(); i++) {
26924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            snprintf(buffer, SIZE, "    input %zu:\n", i);
27024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            write(fd, buffer, strlen(buffer));
27124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mInputProfiles[i]->dump(fd);
27224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
27324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
27424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    if (mDeclaredDevices.size()) {
27524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        write(fd, "  - devices:\n", strlen("  - devices:\n"));
27624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        for (size_t i = 0; i < mDeclaredDevices.size(); i++) {
27724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown            mDeclaredDevices[i]->dump(fd, 4, i);
27824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown        }
27924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown    }
28024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown}
28124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown
28224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} //namespace android
28324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown