Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "APM::Devices"
     18 //#define LOG_NDEBUG 0
     19 
     20 #include "DeviceDescriptor.h"
     21 #include "TypeConverter.h"
     22 #include "AudioGain.h"
     23 #include "HwModule.h"
     24 
     25 namespace android {
     26 
     27 DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const String8 &tagName) :
     28     AudioPort(String8(""), AUDIO_PORT_TYPE_DEVICE,
     29               audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
     30                                              AUDIO_PORT_ROLE_SOURCE),
     31     mAddress(""), mTagName(tagName), mDeviceType(type), mId(0)
     32 {
     33     if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) {
     34         mAddress = String8("0");
     35     }
     36 }
     37 
     38 audio_port_handle_t DeviceDescriptor::getId() const
     39 {
     40     return mId;
     41 }
     42 
     43 void DeviceDescriptor::attach(const sp<HwModule>& module)
     44 {
     45     AudioPort::attach(module);
     46     mId = getNextUniqueId();
     47 }
     48 
     49 bool DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
     50 {
     51     // Devices are considered equal if they:
     52     // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
     53     // - have the same address
     54     if (other == 0) {
     55         return false;
     56     }
     57     return (mDeviceType == other->mDeviceType) && (mAddress == other->mAddress);
     58 }
     59 
     60 void DeviceVector::refreshTypes()
     61 {
     62     mDeviceTypes = AUDIO_DEVICE_NONE;
     63     for(size_t i = 0; i < size(); i++) {
     64         mDeviceTypes |= itemAt(i)->type();
     65     }
     66     ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes);
     67 }
     68 
     69 ssize_t DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
     70 {
     71     for(size_t i = 0; i < size(); i++) {
     72         if (item->equals(itemAt(i))) {
     73             return i;
     74         }
     75     }
     76     return -1;
     77 }
     78 
     79 void DeviceVector::add(const DeviceVector &devices)
     80 {
     81     for (size_t i = 0; i < devices.size(); i++) {
     82         sp<DeviceDescriptor> device = devices.itemAt(i);
     83         if (indexOf(device) < 0 && SortedVector::add(device) >= 0) {
     84             refreshTypes();
     85         }
     86     }
     87 }
     88 
     89 ssize_t DeviceVector::add(const sp<DeviceDescriptor>& item)
     90 {
     91     ssize_t ret = indexOf(item);
     92 
     93     if (ret < 0) {
     94         ret = SortedVector::add(item);
     95         if (ret >= 0) {
     96             refreshTypes();
     97         }
     98     } else {
     99         ALOGW("DeviceVector::add device %08x already in", item->type());
    100         ret = -1;
    101     }
    102     return ret;
    103 }
    104 
    105 ssize_t DeviceVector::remove(const sp<DeviceDescriptor>& item)
    106 {
    107     size_t i;
    108     ssize_t ret = indexOf(item);
    109 
    110     if (ret < 0) {
    111         ALOGW("DeviceVector::remove device %08x not in", item->type());
    112     } else {
    113         ret = SortedVector::removeAt(ret);
    114         if (ret >= 0) {
    115             refreshTypes();
    116         }
    117     }
    118     return ret;
    119 }
    120 
    121 audio_devices_t DeviceVector::getDevicesFromHwModule(audio_module_handle_t moduleHandle) const
    122 {
    123     audio_devices_t devices = AUDIO_DEVICE_NONE;
    124     for (size_t i = 0; i < size(); i++) {
    125         if (itemAt(i)->getModuleHandle() == moduleHandle) {
    126             devices |= itemAt(i)->type();
    127         }
    128     }
    129     return devices;
    130 }
    131 
    132 sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, String8 address) const
    133 {
    134     sp<DeviceDescriptor> device;
    135     for (size_t i = 0; i < size(); i++) {
    136         if (itemAt(i)->type() == type) {
    137             if (address == "" || itemAt(i)->mAddress == address) {
    138                 device = itemAt(i);
    139                 if (itemAt(i)->mAddress == address) {
    140                     break;
    141                 }
    142             }
    143         }
    144     }
    145     ALOGV("DeviceVector::getDevice() for type %08x address %s found %p",
    146           type, address.string(), device.get());
    147     return device;
    148 }
    149 
    150 sp<DeviceDescriptor> DeviceVector::getDeviceFromId(audio_port_handle_t id) const
    151 {
    152     sp<DeviceDescriptor> device;
    153     for (size_t i = 0; i < size(); i++) {
    154         if (itemAt(i)->getId() == id) {
    155             device = itemAt(i);
    156             break;
    157         }
    158     }
    159     return device;
    160 }
    161 
    162 DeviceVector DeviceVector::getDevicesFromType(audio_devices_t type) const
    163 {
    164     DeviceVector devices;
    165     bool isOutput = audio_is_output_devices(type);
    166     type &= ~AUDIO_DEVICE_BIT_IN;
    167     for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) {
    168         bool curIsOutput = audio_is_output_devices(itemAt(i)->mDeviceType);
    169         audio_devices_t curType = itemAt(i)->mDeviceType & ~AUDIO_DEVICE_BIT_IN;
    170         if ((isOutput == curIsOutput) && ((type & curType) != 0)) {
    171             devices.add(itemAt(i));
    172             type &= ~curType;
    173             ALOGV("DeviceVector::getDevicesFromType() for type %x found %p",
    174                   itemAt(i)->type(), itemAt(i).get());
    175         }
    176     }
    177     return devices;
    178 }
    179 
    180 DeviceVector DeviceVector::getDevicesFromTypeAddr(
    181         audio_devices_t type, String8 address) const
    182 {
    183     DeviceVector devices;
    184     for (size_t i = 0; i < size(); i++) {
    185         if (itemAt(i)->type() == type) {
    186             if (itemAt(i)->mAddress == address) {
    187                 devices.add(itemAt(i));
    188             }
    189         }
    190     }
    191     return devices;
    192 }
    193 
    194 sp<DeviceDescriptor> DeviceVector::getDeviceFromTagName(const String8 &tagName) const
    195 {
    196     sp<DeviceDescriptor> device;
    197     for (size_t i = 0; i < size(); i++) {
    198         if (itemAt(i)->getTagName() == tagName) {
    199             device = itemAt(i);
    200             break;
    201         }
    202     }
    203     return device;
    204 }
    205 
    206 status_t DeviceVector::dump(int fd, const String8 &tag, int spaces, bool verbose) const
    207 {
    208     if (isEmpty()) {
    209         return NO_ERROR;
    210     }
    211     const size_t SIZE = 256;
    212     char buffer[SIZE];
    213 
    214     snprintf(buffer, SIZE, "%*s- %s devices:\n", spaces, "", tag.string());
    215     write(fd, buffer, strlen(buffer));
    216     for (size_t i = 0; i < size(); i++) {
    217         itemAt(i)->dump(fd, spaces + 2, i, verbose);
    218     }
    219     return NO_ERROR;
    220 }
    221 
    222 void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
    223                                          const struct audio_port_config *srcConfig) const
    224 {
    225     dstConfig->config_mask = AUDIO_PORT_CONFIG_GAIN;
    226     if (mSamplingRate != 0) {
    227         dstConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
    228     }
    229     if (mChannelMask != AUDIO_CHANNEL_NONE) {
    230         dstConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
    231     }
    232     if (mFormat != AUDIO_FORMAT_INVALID) {
    233         dstConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT;
    234     }
    235 
    236     if (srcConfig != NULL) {
    237         dstConfig->config_mask |= srcConfig->config_mask;
    238     }
    239 
    240     AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
    241 
    242     dstConfig->id = mId;
    243     dstConfig->role = audio_is_output_device(mDeviceType) ?
    244                         AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
    245     dstConfig->type = AUDIO_PORT_TYPE_DEVICE;
    246     dstConfig->ext.device.type = mDeviceType;
    247 
    248     //TODO Understand why this test is necessary. i.e. why at boot time does it crash
    249     // without the test?
    250     // This has been demonstrated to NOT be true (at start up)
    251     // ALOG_ASSERT(mModule != NULL);
    252     dstConfig->ext.device.hw_module = mModule != 0 ? mModule->mHandle : AUDIO_MODULE_HANDLE_NONE;
    253     strncpy(dstConfig->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
    254 }
    255 
    256 void DeviceDescriptor::toAudioPort(struct audio_port *port) const
    257 {
    258     ALOGV("DeviceDescriptor::toAudioPort() handle %d type %x", mId, mDeviceType);
    259     AudioPort::toAudioPort(port);
    260     port->id = mId;
    261     toAudioPortConfig(&port->active_config);
    262     port->ext.device.type = mDeviceType;
    263     port->ext.device.hw_module = mModule->mHandle;
    264     strncpy(port->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
    265 }
    266 
    267 void DeviceDescriptor::importAudioPort(const sp<AudioPort> port) {
    268     AudioPort::importAudioPort(port);
    269     port->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
    270 }
    271 
    272 status_t DeviceDescriptor::dump(int fd, int spaces, int index, bool verbose) const
    273 {
    274     const size_t SIZE = 256;
    275     char buffer[SIZE];
    276     String8 result;
    277 
    278     snprintf(buffer, SIZE, "%*sDevice %d:\n", spaces, "", index+1);
    279     result.append(buffer);
    280     if (mId != 0) {
    281         snprintf(buffer, SIZE, "%*s- id: %2d\n", spaces, "", mId);
    282         result.append(buffer);
    283     }
    284     if (!mTagName.isEmpty()) {
    285         snprintf(buffer, SIZE, "%*s- tag name: %s\n", spaces, "", mTagName.string());
    286         result.append(buffer);
    287     }
    288     std::string deviceLiteral;
    289     if (DeviceConverter::toString(mDeviceType, deviceLiteral)) {
    290         snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "", deviceLiteral.c_str());
    291         result.append(buffer);
    292     }
    293     if (mAddress.size() != 0) {
    294         snprintf(buffer, SIZE, "%*s- address: %-32s\n", spaces, "", mAddress.string());
    295         result.append(buffer);
    296     }
    297     write(fd, result.string(), result.size());
    298     AudioPort::dump(fd, spaces, verbose);
    299 
    300     return NO_ERROR;
    301 }
    302 
    303 void DeviceDescriptor::log() const
    304 {
    305     std::string device;
    306     DeviceConverter::toString(mDeviceType, device);
    307     ALOGI("Device id:%d type:0x%X:%s, addr:%s", mId,  mDeviceType, device.c_str(),
    308           mAddress.string());
    309 
    310     AudioPort::log("  ");
    311 }
    312 
    313 }; // namespace android
    314