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::HwModule" 1856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi//#define LOG_NDEBUG 0 1956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 20ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "HwModule.h" 21ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "IOProfile.h" 2298cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie#include "AudioGain.h" 2353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie#include <policy.h> 24cbc8f617c1aebef5d041fa40dcd38a5466690b99Mikhail Naganov#include <system/audio.h> 2556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 2656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivinamespace android { 2756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 289ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail NaganovHwModule::HwModule(const char *name, uint32_t halVersionMajor, uint32_t halVersionMinor) 29a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie : mName(String8(name)), 309ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov mHandle(AUDIO_MODULE_HANDLE_NONE) 3156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 329ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov setHalVersion(halVersionMajor, halVersionMinor); 3356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 3456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 3556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel TriviHwModule::~HwModule() 3656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 3756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (size_t i = 0; i < mOutputProfiles.size(); i++) { 38a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie mOutputProfiles[i]->clearSupportedDevices(); 3956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 4056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (size_t i = 0; i < mInputProfiles.size(); i++) { 41a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie mInputProfiles[i]->clearSupportedDevices(); 4256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 4356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 4456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 45e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t HwModule::addOutputProfile(const String8& name, const audio_config_t *config, 46e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh audio_devices_t device, const String8& address) 4756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 48a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie sp<IOProfile> profile = new OutputProfile(name); 4956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 50112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie profile->addAudioProfile(new AudioProfile(config->format, config->channel_mask, 51112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie config->sample_rate)); 5256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 537288ab87a7aa730ffe97d7dc7e118123107bfceaEric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device); 5456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi devDesc->mAddress = address; 55a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie profile->addSupportedDevice(devDesc); 5656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 57a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie return addOutputProfile(profile); 58a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie} 59a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie 60a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffiestatus_t HwModule::addOutputProfile(const sp<IOProfile> &profile) 61a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie{ 62322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent profile->attach(this); 6356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mOutputProfiles.add(profile); 64cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie mPorts.add(profile); 65a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie return NO_ERROR; 66a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie} 6756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 68a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffiestatus_t HwModule::addInputProfile(const sp<IOProfile> &profile) 69a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie{ 70a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie profile->attach(this); 71a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie mInputProfiles.add(profile); 72cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie mPorts.add(profile); 7356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return NO_ERROR; 7456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 7556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 76a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffiestatus_t HwModule::addProfile(const sp<IOProfile> &profile) 77a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie{ 78a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie switch (profile->getRole()) { 79a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie case AUDIO_PORT_ROLE_SOURCE: 80a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie return addOutputProfile(profile); 81a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie case AUDIO_PORT_ROLE_SINK: 82a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie return addInputProfile(profile); 83a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie case AUDIO_PORT_ROLE_NONE: 84a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie return BAD_VALUE; 85a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie } 86a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie return BAD_VALUE; 87a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie} 88a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie 89a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffievoid HwModule::setProfiles(const IOProfileCollection &profiles) 90a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie{ 91a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie for (size_t i = 0; i < profiles.size(); i++) { 92a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie addProfile(profiles[i]); 93a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie } 94a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie} 95a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie 96e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t HwModule::removeOutputProfile(const String8& name) 9756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 9856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (size_t i = 0; i < mOutputProfiles.size(); i++) { 99a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie if (mOutputProfiles[i]->getName() == name) { 10056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mOutputProfiles.removeAt(i); 10156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi break; 10256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 10356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 10456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 10556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return NO_ERROR; 10656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 10756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 108e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t HwModule::addInputProfile(const String8& name, const audio_config_t *config, 109e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh audio_devices_t device, const String8& address) 11056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 111a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie sp<IOProfile> profile = new InputProfile(name); 112112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie profile->addAudioProfile(new AudioProfile(config->format, config->channel_mask, 113112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie config->sample_rate)); 11456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 1157288ab87a7aa730ffe97d7dc7e118123107bfceaEric Laurent sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device); 11656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi devDesc->mAddress = address; 117a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie profile->addSupportedDevice(devDesc); 11856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 1197b279bbc24139ee1e01b58055ca94926ec18e2e9Eric Laurent ALOGV("addInputProfile() name %s rate %d mask 0x%08x", 1207b279bbc24139ee1e01b58055ca94926ec18e2e9Eric Laurent name.string(), config->sample_rate, config->channel_mask); 12156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 122a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie return addInputProfile(profile); 12356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 12456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 125e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehstatus_t HwModule::removeInputProfile(const String8& name) 12656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 12756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (size_t i = 0; i < mInputProfiles.size(); i++) { 128a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie if (mInputProfiles[i]->getName() == name) { 12956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mInputProfiles.removeAt(i); 13056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi break; 13156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 13256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 13356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 13456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return NO_ERROR; 13556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 13656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 137cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffievoid HwModule::setDeclaredDevices(const DeviceVector &devices) 138cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie{ 139cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie mDeclaredDevices = devices; 140cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie for (size_t i = 0; i < devices.size(); i++) { 141cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie mPorts.add(devices[i]); 142cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 143cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie} 144cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie 145cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffiesp<DeviceDescriptor> HwModule::getRouteSinkDevice(const sp<AudioRoute> &route) const 146cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie{ 147cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie sp<DeviceDescriptor> sinkDevice = 0; 148cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie if (route->getSink()->getType() == AUDIO_PORT_TYPE_DEVICE) { 149cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie sinkDevice = mDeclaredDevices.getDeviceFromTagName(route->getSink()->getTagName()); 150cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 151cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie return sinkDevice; 152cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie} 153cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie 154cbb3044d6bfa9ab30c83b67874f40344e29805e1François GaffieDeviceVector HwModule::getRouteSourceDevices(const sp<AudioRoute> &route) const 155cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie{ 156cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie DeviceVector sourceDevices; 1572478d528186436f693b02c3534f04425086b638cMikhail Naganov for (const auto& source : route->getSources()) { 1582478d528186436f693b02c3534f04425086b638cMikhail Naganov if (source->getType() == AUDIO_PORT_TYPE_DEVICE) { 1592478d528186436f693b02c3534f04425086b638cMikhail Naganov sourceDevices.add(mDeclaredDevices.getDeviceFromTagName(source->getTagName())); 160cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 161cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 162cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie return sourceDevices; 163cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie} 164cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie 165cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffievoid HwModule::setRoutes(const AudioRouteVector &routes) 166cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie{ 167cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie mRoutes = routes; 168cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie // Now updating the streams (aka IOProfile until now) supported devices 169cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie refreshSupportedDevices(); 170cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie} 171cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie 172cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffievoid HwModule::refreshSupportedDevices() 173cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie{ 174cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie // Now updating the streams (aka IOProfile until now) supported devices 1752478d528186436f693b02c3534f04425086b638cMikhail Naganov for (const auto& stream : mInputProfiles) { 176cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie DeviceVector sourceDevices; 1772478d528186436f693b02c3534f04425086b638cMikhail Naganov for (const auto& route : stream->getRoutes()) { 1782478d528186436f693b02c3534f04425086b638cMikhail Naganov sp<AudioPort> sink = route->getSink(); 179cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie if (sink == 0 || stream != sink) { 180cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie ALOGE("%s: Invalid route attached to input stream", __FUNCTION__); 181cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie continue; 182cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 1832478d528186436f693b02c3534f04425086b638cMikhail Naganov DeviceVector sourceDevicesForRoute = getRouteSourceDevices(route); 184cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie if (sourceDevicesForRoute.isEmpty()) { 185cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie ALOGE("%s: invalid source devices for %s", __FUNCTION__, stream->getName().string()); 186cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie continue; 187cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 188cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie sourceDevices.add(sourceDevicesForRoute); 189cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 190cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie if (sourceDevices.isEmpty()) { 191cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie ALOGE("%s: invalid source devices for %s", __FUNCTION__, stream->getName().string()); 192cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie continue; 193cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 194cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie stream->setSupportedDevices(sourceDevices); 195cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 1962478d528186436f693b02c3534f04425086b638cMikhail Naganov for (const auto& stream : mOutputProfiles) { 197cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie DeviceVector sinkDevices; 1982478d528186436f693b02c3534f04425086b638cMikhail Naganov for (const auto& route : stream->getRoutes()) { 1992478d528186436f693b02c3534f04425086b638cMikhail Naganov sp<AudioPort> source = route->getSources().findByTagName(stream->getTagName()); 200cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie if (source == 0 || stream != source) { 201cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie ALOGE("%s: Invalid route attached to output stream", __FUNCTION__); 202cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie continue; 203cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 2042478d528186436f693b02c3534f04425086b638cMikhail Naganov sp<DeviceDescriptor> sinkDevice = getRouteSinkDevice(route); 205cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie if (sinkDevice == 0) { 206cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie ALOGE("%s: invalid sink device for %s", __FUNCTION__, stream->getName().string()); 207cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie continue; 208cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 209cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie sinkDevices.add(sinkDevice); 210cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 211cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie stream->setSupportedDevices(sinkDevices); 212cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 213cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie} 21456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 215a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganovvoid HwModule::setHandle(audio_module_handle_t handle) { 216a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov ALOGW_IF(mHandle != AUDIO_MODULE_HANDLE_NONE, 217a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov "HwModule handle is changing from %d to %d", mHandle, handle); 218a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov mHandle = handle; 219a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov} 220a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov 22156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid HwModule::dump(int fd) 22256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 22356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi const size_t SIZE = 256; 22456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi char buffer[SIZE]; 22556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi String8 result; 22656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 227a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie snprintf(buffer, SIZE, " - name: %s\n", getName()); 22856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 22956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " - handle: %d\n", mHandle); 23056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 2319ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov snprintf(buffer, SIZE, " - version: %u.%u\n", getHalVersionMajor(), getHalVersionMinor()); 23256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 23356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, result.string(), result.size()); 23456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (mOutputProfiles.size()) { 23556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, " - outputs:\n", strlen(" - outputs:\n")); 23656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (size_t i = 0; i < mOutputProfiles.size(); i++) { 23756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " output %zu:\n", i); 23856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, buffer, strlen(buffer)); 23956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mOutputProfiles[i]->dump(fd); 24056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 24156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 24256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (mInputProfiles.size()) { 24356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, " - inputs:\n", strlen(" - inputs:\n")); 24456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (size_t i = 0; i < mInputProfiles.size(); i++) { 24556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " input %zu:\n", i); 24656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, buffer, strlen(buffer)); 24756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mInputProfiles[i]->dump(fd); 24856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 24956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 250112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mDeclaredDevices.dump(fd, String8("Declared"), 2, true); 251f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie mRoutes.dump(fd, 2); 25256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 25356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 25453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffiesp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const 25553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 256d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov for (const auto& module : *this) { 257d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov if (strcmp(module->getName(), name) == 0) { 258d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov return module; 25953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 26053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 261d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov return nullptr; 26253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 26353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 26453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffiesp <HwModule> HwModuleCollection::getModuleForDevice(audio_devices_t device) const 26553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 266d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov for (const auto& module : *this) { 267a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov const auto& profiles = audio_is_output_device(device) ? 268a5e165d3a9074c09b67df5a89aa26b153cf69562Mikhail Naganov module->getOutputProfiles() : module->getInputProfiles(); 269d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov for (const auto& profile : profiles) { 270d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov if (profile->supportDevice(device)) { 271d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov return module; 27253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 27353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 27453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 275d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov return nullptr; 27653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 27753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 278d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganovsp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices_t device, 279d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov const char *device_address, 280d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov const char *device_name, 281d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov bool matchAdress) const 28253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 283d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov String8 address = (device_address == nullptr) ? String8("") : String8(device_address); 28453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie // handle legacy remote submix case where the address was not always specified 28553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (device_distinguishes_on_address(device) && (address.length() == 0)) { 28653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie address = String8("0"); 28753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 28853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 289d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov for (const auto& hwModule : *this) { 290634b71478742310960f3fdb4241e70a0735712c4Eric Laurent DeviceVector declaredDevices = hwModule->getDeclaredDevices(); 291634b71478742310960f3fdb4241e70a0735712c4Eric Laurent DeviceVector deviceList = declaredDevices.getDevicesFromTypeAddr(device, address); 29253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (!deviceList.isEmpty()) { 29353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return deviceList.itemAt(0); 29453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 295634b71478742310960f3fdb4241e70a0735712c4Eric Laurent if (!matchAdress) { 296634b71478742310960f3fdb4241e70a0735712c4Eric Laurent deviceList = declaredDevices.getDevicesFromType(device); 297634b71478742310960f3fdb4241e70a0735712c4Eric Laurent if (!deviceList.isEmpty()) { 298634b71478742310960f3fdb4241e70a0735712c4Eric Laurent return deviceList.itemAt(0); 299634b71478742310960f3fdb4241e70a0735712c4Eric Laurent } 300634b71478742310960f3fdb4241e70a0735712c4Eric Laurent } 30153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 30253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 3031d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois Gaffie sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device); 3041d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois Gaffie devDesc->setName(String8(device_name)); 30553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie devDesc->mAddress = address; 30653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return devDesc; 30753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 30853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 30953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffiestatus_t HwModuleCollection::dump(int fd) const 31053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 31153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie const size_t SIZE = 256; 31253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie char buffer[SIZE]; 31353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 31453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie snprintf(buffer, SIZE, "\nHW Modules dump:\n"); 31553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie write(fd, buffer, strlen(buffer)); 31653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 31753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1); 31853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie write(fd, buffer, strlen(buffer)); 31953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie itemAt(i)->dump(fd); 32053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 32153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return NO_ERROR; 32253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 32353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 324d4120148e72b2352f19f74dd493e903992371ef9Mikhail Naganov 32556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} //namespace android 326