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)
53f7f85438503e6964aba3ddabd6228e7fefb36735Jean-Michel Trivi    // - have the same address
54493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent    if (other == 0) {
55493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent        return false;
56493404d8c396e15ed73455acd39aa0f1940996e2Eric Laurent    }
57f7f85438503e6964aba3ddabd6228e7fefb36735Jean-Michel Trivi    return (mDeviceType == other->mDeviceType) && (mAddress == other->mAddress);
5856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
5956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
6056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid DeviceVector::refreshTypes()
6156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
6256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    mDeviceTypes = AUDIO_DEVICE_NONE;
6356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for(size_t i = 0; i < size(); i++) {
6453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        mDeviceTypes |= itemAt(i)->type();
6556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
6656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes);
6756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
6856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
6956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivissize_t DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
7056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
7156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for(size_t i = 0; i < size(); i++) {
7256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        if (item->equals(itemAt(i))) {
7356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            return i;
7456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
7556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
7656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return -1;
7756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
7856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
79a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffievoid DeviceVector::add(const DeviceVector &devices)
80a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie{
81a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    for (size_t i = 0; i < devices.size(); i++) {
82a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        sp<DeviceDescriptor> device = devices.itemAt(i);
83a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        if (indexOf(device) < 0 && SortedVector::add(device) >= 0) {
84a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie            refreshTypes();
85a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        }
86a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    }
87a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie}
88a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie
8956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivissize_t DeviceVector::add(const sp<DeviceDescriptor>& item)
9056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
9156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    ssize_t ret = indexOf(item);
9256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
9356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (ret < 0) {
9456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        ret = SortedVector::add(item);
9556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        if (ret >= 0) {
9656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            refreshTypes();
9756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
9856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    } else {
9953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        ALOGW("DeviceVector::add device %08x already in", item->type());
10056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        ret = -1;
10156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
10256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return ret;
10356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
10456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
10556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivissize_t DeviceVector::remove(const sp<DeviceDescriptor>& item)
10656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
10756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    ssize_t ret = indexOf(item);
10856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
10956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (ret < 0) {
11053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        ALOGW("DeviceVector::remove device %08x not in", item->type());
11156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    } else {
11256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        ret = SortedVector::removeAt(ret);
11356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        if (ret >= 0) {
11456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            refreshTypes();
11556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
11656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
11756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return ret;
11856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
11956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
12053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffieaudio_devices_t DeviceVector::getDevicesFromHwModule(audio_module_handle_t moduleHandle) const
12153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
12253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    audio_devices_t devices = AUDIO_DEVICE_NONE;
12353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
12453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        if (itemAt(i)->getModuleHandle() == moduleHandle) {
12553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie            devices |= itemAt(i)->type();
12653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        }
12753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
12853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return devices;
12953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
13053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
131e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehsp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8& address) const
13256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
13356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    sp<DeviceDescriptor> device;
13456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (size_t i = 0; i < size(); i++) {
13553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        if (itemAt(i)->type() == type) {
13656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            if (address == "" || itemAt(i)->mAddress == address) {
13756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                device = itemAt(i);
13856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                if (itemAt(i)->mAddress == address) {
13956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                    break;
14056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                }
14156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            }
14256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
14356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
14456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    ALOGV("DeviceVector::getDevice() for type %08x address %s found %p",
14556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi          type, address.string(), device.get());
14656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return device;
14756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
14856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
14956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivisp<DeviceDescriptor> DeviceVector::getDeviceFromId(audio_port_handle_t id) const
15056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
15156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    sp<DeviceDescriptor> device;
15256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (size_t i = 0; i < size(); i++) {
153322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent        if (itemAt(i)->getId() == id) {
15456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            device = itemAt(i);
15556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            break;
15656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
15756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
15856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return device;
15956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
16056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
16156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel TriviDeviceVector DeviceVector::getDevicesFromType(audio_devices_t type) const
16256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
16356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    DeviceVector devices;
1644c91f90c72e74474fad7f6a99ae7926c8d1f2504Eric Laurent    bool isOutput = audio_is_output_devices(type);
1654c91f90c72e74474fad7f6a99ae7926c8d1f2504Eric Laurent    type &= ~AUDIO_DEVICE_BIT_IN;
16656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) {
1674c91f90c72e74474fad7f6a99ae7926c8d1f2504Eric Laurent        bool curIsOutput = audio_is_output_devices(itemAt(i)->mDeviceType);
1684c91f90c72e74474fad7f6a99ae7926c8d1f2504Eric Laurent        audio_devices_t curType = itemAt(i)->mDeviceType & ~AUDIO_DEVICE_BIT_IN;
1694c91f90c72e74474fad7f6a99ae7926c8d1f2504Eric Laurent        if ((isOutput == curIsOutput) && ((type & curType) != 0)) {
17056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            devices.add(itemAt(i));
1714c91f90c72e74474fad7f6a99ae7926c8d1f2504Eric Laurent            type &= ~curType;
17256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            ALOGV("DeviceVector::getDevicesFromType() for type %x found %p",
17353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie                  itemAt(i)->type(), itemAt(i).get());
17456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
17556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
17656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return devices;
17756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
17856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
17956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel TriviDeviceVector DeviceVector::getDevicesFromTypeAddr(
180e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh        audio_devices_t type, const String8& address) const
18156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
18256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    DeviceVector devices;
18356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (size_t i = 0; i < size(); i++) {
18453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie        if (itemAt(i)->type() == type) {
18556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            if (itemAt(i)->mAddress == address) {
18656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                devices.add(itemAt(i));
18756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            }
18856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
18956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
19056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return devices;
19156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
19256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
1931d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois Gaffiesp<DeviceDescriptor> DeviceVector::getDeviceFromTagName(const String8 &tagName) const
19456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
19556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    sp<DeviceDescriptor> device;
19656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    for (size_t i = 0; i < size(); i++) {
1971d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois Gaffie        if (itemAt(i)->getTagName() == tagName) {
19856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            device = itemAt(i);
19956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi            break;
20056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        }
20156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
20256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return device;
20356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
20456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
205112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffiestatus_t DeviceVector::dump(int fd, const String8 &tag, int spaces, bool verbose) const
20653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{
207112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    if (isEmpty()) {
208112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie        return NO_ERROR;
209112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    }
21053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    const size_t SIZE = 256;
21153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    char buffer[SIZE];
21253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
213f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie    snprintf(buffer, SIZE, "%*s- %s devices:\n", spaces, "", tag.string());
21453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    write(fd, buffer, strlen(buffer));
21553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    for (size_t i = 0; i < size(); i++) {
216f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie        itemAt(i)->dump(fd, spaces + 2, i, verbose);
21753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    }
21853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie    return NO_ERROR;
21953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie}
22053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie
22156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
22256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                                         const struct audio_port_config *srcConfig) const
22356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
2248ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent    dstConfig->config_mask = AUDIO_PORT_CONFIG_GAIN;
2258ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent    if (mSamplingRate != 0) {
2268ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent        dstConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
2278ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent    }
2288ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent    if (mChannelMask != AUDIO_CHANNEL_NONE) {
2298ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent        dstConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
2308ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent    }
2318ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent    if (mFormat != AUDIO_FORMAT_INVALID) {
2328ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent        dstConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT;
2338ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent    }
2348ae73129e7e79d826b293238c2f037f723d0e6e8Eric Laurent
23556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (srcConfig != NULL) {
23656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        dstConfig->config_mask |= srcConfig->config_mask;
23756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
23856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
23956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
24056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
24156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->id = mId;
24256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->role = audio_is_output_device(mDeviceType) ?
24356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi                        AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
24456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->type = AUDIO_PORT_TYPE_DEVICE;
24556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    dstConfig->ext.device.type = mDeviceType;
24656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
24756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    //TODO Understand why this test is necessary. i.e. why at boot time does it crash
24856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    // without the test?
24956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    // This has been demonstrated to NOT be true (at start up)
25056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    // ALOG_ASSERT(mModule != NULL);
251a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten    dstConfig->ext.device.hw_module = mModule != 0 ? mModule->mHandle : AUDIO_MODULE_HANDLE_NONE;
25256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    strncpy(dstConfig->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
25356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
25456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
25556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid DeviceDescriptor::toAudioPort(struct audio_port *port) const
25656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
25756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    ALOGV("DeviceDescriptor::toAudioPort() handle %d type %x", mId, mDeviceType);
25856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    AudioPort::toAudioPort(port);
25956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    port->id = mId;
26056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    toAudioPortConfig(&port->active_config);
26156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    port->ext.device.type = mDeviceType;
26256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    port->ext.device.hw_module = mModule->mHandle;
26356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    strncpy(port->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
26456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
26556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
266e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid DeviceDescriptor::importAudioPort(const sp<AudioPort>& port) {
267cc750d3604b33a92374253b12dd739dc06440aadEric Laurent    AudioPort::importAudioPort(port);
268112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    port->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
269cc750d3604b33a92374253b12dd739dc06440aadEric Laurent}
270cc750d3604b33a92374253b12dd739dc06440aadEric Laurent
271112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffiestatus_t DeviceDescriptor::dump(int fd, int spaces, int index, bool verbose) const
27256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{
27356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    const size_t SIZE = 256;
27456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    char buffer[SIZE];
27556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    String8 result;
27656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
27756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    snprintf(buffer, SIZE, "%*sDevice %d:\n", spaces, "", index+1);
27856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    result.append(buffer);
27956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (mId != 0) {
28056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        snprintf(buffer, SIZE, "%*s- id: %2d\n", spaces, "", mId);
28156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        result.append(buffer);
28256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
283cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie    if (!mTagName.isEmpty()) {
284cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie        snprintf(buffer, SIZE, "%*s- tag name: %s\n", spaces, "", mTagName.string());
285cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie        result.append(buffer);
286cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie    }
287a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    std::string deviceLiteral;
288913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov    if (deviceToString(mDeviceType, deviceLiteral)) {
289a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "", deviceLiteral.c_str());
290a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie        result.append(buffer);
291a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    }
29256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    if (mAddress.size() != 0) {
29356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        snprintf(buffer, SIZE, "%*s- address: %-32s\n", spaces, "", mAddress.string());
29456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi        result.append(buffer);
29556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    }
29656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    write(fd, result.string(), result.size());
297112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie    AudioPort::dump(fd, spaces, verbose);
29856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
29956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi    return NO_ERROR;
30056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}
30156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi
302aa9811945f575614b3482d09e4d969792701cebbPaul McLeanvoid DeviceDescriptor::log() const
303aa9811945f575614b3482d09e4d969792701cebbPaul McLean{
304a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    std::string device;
305913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov    deviceToString(mDeviceType, device);
306a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie    ALOGI("Device id:%d type:0x%X:%s, addr:%s", mId,  mDeviceType, device.c_str(),
307aa9811945f575614b3482d09e4d969792701cebbPaul McLean          mAddress.string());
308aa9811945f575614b3482d09e4d969792701cebbPaul McLean
309aa9811945f575614b3482d09e4d969792701cebbPaul McLean    AudioPort::log("  ");
310aa9811945f575614b3482d09e4d969792701cebbPaul McLean}
311aa9811945f575614b3482d09e4d969792701cebbPaul McLean
31256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}; // namespace android
313