DeviceDescriptor.cpp revision 112b0af826aeca45855690b9c105b2cdf9938bbe
156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi/*
256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Copyright (C) 2015 The Android Open Source Project
356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *
456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * you may not use this file except in compliance with the License.
656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * You may obtain a copy of the License at
756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *
856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi *
1056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
1156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
1256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * See the License for the specific language governing permissions and
1456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * limitations under the License.
1556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi */
1656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
1756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi#define LOG_TAG "APM::Devices"
1856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi//#define LOG_NDEBUG 0
1956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
2098cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie#include "DeviceDescriptor.h"
21a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie#include "TypeConverter.h"
2298cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie#include "AudioGain.h"
23ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "HwModule.h"
2456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
2556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivinamespace android {
2656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
271d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois GaffieDeviceDescriptor::DeviceDescriptor(audio_devices_t type, const String8 &tagName) :
287288ab87a7aa730ffe97d7dc7e118123107bfceaEric Laurent    AudioPort(String8(""), AUDIO_PORT_TYPE_DEVICE,
2953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie              audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
30322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent                                             AUDIO_PORT_ROLE_SOURCE),
311d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois Gaffie    mAddress(""), mTagName(tagName), mDeviceType(type), mId(0)
3256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
331d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois Gaffie    if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) {
341d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois Gaffie        mAddress = String8("0");
351d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois Gaffie    }
3656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
3756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
38322b4d25387a04c9afebe998326d005bbdf17edeEric Laurentaudio_port_handle_t DeviceDescriptor::getId() const
39322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent{
40322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    return mId;
41322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent}
42322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent
43322b4d25387a04c9afebe998326d005bbdf17edeEric Laurentvoid DeviceDescriptor::attach(const sp<HwModule>& module)
44322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent{
45322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    AudioPort::attach(module);
46322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent    mId = getNextUniqueId();
47322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent}
48322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent
4956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
5056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
5156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    // Devices are considered equal if they:
5256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
5356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    // - have the same address or one device does not specify the address
5456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    // - have the same channel mask or one device does not specify the channel mask
55493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent    if (other == 0) {
56493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent        return false;
57493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent    }
5856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return (mDeviceType == other->mDeviceType) &&
5956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi           (mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) &&
6056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi           (mChannelMask == 0 || other->mChannelMask == 0 ||
6156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                mChannelMask == other->mChannelMask);
6256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
6356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
6456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid DeviceVector::refreshTypes()
6556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
6656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    mDeviceTypes = AUDIO_DEVICE_NONE;
6756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for(size_t i = 0; i < size(); i++) {
6853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        mDeviceTypes |= itemAt(i)->type();
6956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
7056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes);
7156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
7256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
7356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivissize_t DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
7456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
7556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for(size_t i = 0; i < size(); i++) {
7656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        if (item->equals(itemAt(i))) {
7756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            return i;
7856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
7956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
8056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return -1;
8156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
8256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
83a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffievoid DeviceVector::add(const DeviceVector &devices)
84a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie{
85a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    for (size_t i = 0; i < devices.size(); i++) {
86a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        sp<DeviceDescriptor> device = devices.itemAt(i);
87a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        if (indexOf(device) < 0 && SortedVector::add(device) >= 0) {
88a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            refreshTypes();
89a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        }
90a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    }
91a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie}
92a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
9356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivissize_t DeviceVector::add(const sp<DeviceDescriptor>& item)
9456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
9556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    ssize_t ret = indexOf(item);
9656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
9756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (ret < 0) {
9856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        ret = SortedVector::add(item);
9956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        if (ret >= 0) {
10056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            refreshTypes();
10156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
10256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    } else {
10353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        ALOGW("DeviceVector::add device %08x already in", item->type());
10456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        ret = -1;
10556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
10656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return ret;
10756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
10856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
10956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivissize_t DeviceVector::remove(const sp<DeviceDescriptor>& item)
11056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
11156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    size_t i;
11256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    ssize_t ret = indexOf(item);
11356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
11456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (ret < 0) {
11553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        ALOGW("DeviceVector::remove device %08x not in", item->type());
11656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    } else {
11756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        ret = SortedVector::removeAt(ret);
11856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        if (ret >= 0) {
11956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            refreshTypes();
12056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
12156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
12256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return ret;
12356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
12456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
12553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffieaudio_devices_t DeviceVector::getDevicesFromHwModule(audio_module_handle_t moduleHandle) const
12653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
12753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    audio_devices_t devices = AUDIO_DEVICE_NONE;
12853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
12953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        if (itemAt(i)->getModuleHandle() == moduleHandle) {
13053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            devices |= itemAt(i)->type();
13153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        }
13253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
13353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return devices;
13453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
13553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
13656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivisp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, String8 address) const
13756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
13856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    sp<DeviceDescriptor> device;
13956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (size_t i = 0; i < size(); i++) {
14053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        if (itemAt(i)->type() == type) {
14156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            if (address == "" || itemAt(i)->mAddress == address) {
14256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                device = itemAt(i);
14356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                if (itemAt(i)->mAddress == address) {
14456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                    break;
14556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                }
14656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            }
14756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
14856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
14956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    ALOGV("DeviceVector::getDevice() for type %08x address %s found %p",
15056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi          type, address.string(), device.get());
15156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return device;
15256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
15356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
15456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivisp<DeviceDescriptor> DeviceVector::getDeviceFromId(audio_port_handle_t id) const
15556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
15656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    sp<DeviceDescriptor> device;
15756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (size_t i = 0; i < size(); i++) {
158322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent        if (itemAt(i)->getId() == id) {
15956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            device = itemAt(i);
16056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            break;
16156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
16256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
16356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return device;
16456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
16556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
16656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel TriviDeviceVector DeviceVector::getDevicesFromType(audio_devices_t type) const
16756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
16856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    DeviceVector devices;
1694c91f90c72e74474fad7f6a99ae7926c8d1f2504Eric Laurent    bool isOutput = audio_is_output_devices(type);
1704c91f90c72e74474fad7f6a99ae7926c8d1f2504Eric Laurent    type &= ~AUDIO_DEVICE_BIT_IN;
17156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) {
1724c91f90c72e74474fad7f6a99ae7926c8d1f2504Eric Laurent        bool curIsOutput = audio_is_output_devices(itemAt(i)->mDeviceType);
1734c91f90c72e74474fad7f6a99ae7926c8d1f2504Eric Laurent        audio_devices_t curType = itemAt(i)->mDeviceType & ~AUDIO_DEVICE_BIT_IN;
1744c91f90c72e74474fad7f6a99ae7926c8d1f2504Eric Laurent        if ((isOutput == curIsOutput) && ((type & curType) != 0)) {
17556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            devices.add(itemAt(i));
1764c91f90c72e74474fad7f6a99ae7926c8d1f2504Eric Laurent            type &= ~curType;
17756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            ALOGV("DeviceVector::getDevicesFromType() for type %x found %p",
17853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                  itemAt(i)->type(), itemAt(i).get());
17956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
18056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
18156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return devices;
18256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
18356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
18456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel TriviDeviceVector DeviceVector::getDevicesFromTypeAddr(
18556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        audio_devices_t type, String8 address) const
18656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
18756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    DeviceVector devices;
18856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (size_t i = 0; i < size(); i++) {
18953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        if (itemAt(i)->type() == type) {
19056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            if (itemAt(i)->mAddress == address) {
19156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                devices.add(itemAt(i));
19256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            }
19356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
19456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
19556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return devices;
19656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
19756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
1981d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois Gaffiesp<DeviceDescriptor> DeviceVector::getDeviceFromTagName(const String8 &tagName) const
19956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
20056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    sp<DeviceDescriptor> device;
20156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (size_t i = 0; i < size(); i++) {
2021d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois Gaffie        if (itemAt(i)->getTagName() == tagName) {
20356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            device = itemAt(i);
20456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            break;
20556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
20656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
20756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return device;
20856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
20956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
210112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffiestatus_t DeviceVector::dump(int fd, const String8 &tag, int spaces, bool verbose) const
21153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
212112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    if (isEmpty()) {
213112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        return NO_ERROR;
214112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    }
21553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    const size_t SIZE = 256;
21653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    char buffer[SIZE];
21753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
218112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    snprintf(buffer, SIZE, "%*s %s devices:\n", spaces, "", tag.string());
21953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    write(fd, buffer, strlen(buffer));
22053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
221112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        itemAt(i)->dump(fd, spaces + 4, i, verbose);
22253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
22353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return NO_ERROR;
22453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
22553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
22653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffieaudio_policy_dev_state_t DeviceVector::getDeviceConnectionState(const sp<DeviceDescriptor> &devDesc) const
22753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
22853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    ssize_t index = indexOf(devDesc);
22953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return index >= 0 ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
23053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
23153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
23256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
23356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                                         const struct audio_port_config *srcConfig) const
23456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
23556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK|AUDIO_PORT_CONFIG_GAIN;
23656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (srcConfig != NULL) {
23756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        dstConfig->config_mask |= srcConfig->config_mask;
23856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
23956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
24056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
24156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
24256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->id = mId;
24356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->role = audio_is_output_device(mDeviceType) ?
24456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                        AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
24556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->type = AUDIO_PORT_TYPE_DEVICE;
24656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->ext.device.type = mDeviceType;
24756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
24856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    //TODO Understand why this test is necessary. i.e. why at boot time does it crash
24956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    // without the test?
25056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    // This has been demonstrated to NOT be true (at start up)
25156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    // ALOG_ASSERT(mModule != NULL);
252f5d144f7ca773750ea7be371f14f9fc975a15862Eric Laurent    dstConfig->ext.device.hw_module = mModule != 0 ? mModule->mHandle : AUDIO_IO_HANDLE_NONE;
25356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    strncpy(dstConfig->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
25456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
25556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
25656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid DeviceDescriptor::toAudioPort(struct audio_port *port) const
25756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
25856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    ALOGV("DeviceDescriptor::toAudioPort() handle %d type %x", mId, mDeviceType);
25956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    AudioPort::toAudioPort(port);
26056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    port->id = mId;
26156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    toAudioPortConfig(&port->active_config);
26256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    port->ext.device.type = mDeviceType;
26356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    port->ext.device.hw_module = mModule->mHandle;
26456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    strncpy(port->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
26556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
26656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
267cc750d3604b33a92374253b12dd739dc06440aadEric Laurentvoid DeviceDescriptor::importAudioPort(const sp<AudioPort> port) {
268cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    AudioPort::importAudioPort(port);
269112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    port->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
270cc750d3604b33a92374253b12dd739dc06440aadEric Laurent}
271cc750d3604b33a92374253b12dd739dc06440aadEric Laurent
272112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffiestatus_t DeviceDescriptor::dump(int fd, int spaces, int index, bool verbose) const
27356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
27456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    const size_t SIZE = 256;
27556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    char buffer[SIZE];
27656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    String8 result;
27756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
27856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    snprintf(buffer, SIZE, "%*sDevice %d:\n", spaces, "", index+1);
27956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    result.append(buffer);
28056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (mId != 0) {
28156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        snprintf(buffer, SIZE, "%*s- id: %2d\n", spaces, "", mId);
28256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        result.append(buffer);
28356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
284a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    std::string deviceLiteral;
285a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    if (DeviceConverter::toString(mDeviceType, deviceLiteral)) {
286a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "", deviceLiteral.c_str());
287a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        result.append(buffer);
288a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    }
28956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (mAddress.size() != 0) {
29056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        snprintf(buffer, SIZE, "%*s- address: %-32s\n", spaces, "", mAddress.string());
29156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        result.append(buffer);
29256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
29356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    write(fd, result.string(), result.size());
294112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    AudioPort::dump(fd, spaces, verbose);
29556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
29656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return NO_ERROR;
29756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
29856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
299aa9811945f575614b3482d09e4d969792701cebbPaul McLeanvoid DeviceDescriptor::log() const
300aa9811945f575614b3482d09e4d969792701cebbPaul McLean{
301a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    std::string device;
302a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    DeviceConverter::toString(mDeviceType, device);
303a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    ALOGI("Device id:%d type:0x%X:%s, addr:%s", mId,  mDeviceType, device.c_str(),
304aa9811945f575614b3482d09e4d969792701cebbPaul McLean          mAddress.string());
305aa9811945f575614b3482d09e4d969792701cebbPaul McLean
306aa9811945f575614b3482d09e4d969792701cebbPaul McLean    AudioPort::log("  ");
307aa9811945f575614b3482d09e4d969792701cebbPaul McLean}
308aa9811945f575614b3482d09e4d969792701cebbPaul McLean
30956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}; // namespace android
310