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" 2356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi#include <hardware/audio.h> 2453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie#include <policy.h> 2556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 2656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivinamespace android { 2756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 28a8ecc2c72ca26389bd6b0162181d60aaeaca8149François GaffieHwModule::HwModule(const char *name, uint32_t halVersion) 29a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie : mName(String8(name)), 30a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten mHandle(AUDIO_MODULE_HANDLE_NONE), 31a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie mHalVersion(halVersion) 3256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 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 4556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivistatus_t HwModule::addOutputProfile(String8 name, const audio_config_t *config, 46112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie audio_devices_t device, 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 9656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivistatus_t HwModule::removeOutputProfile(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 10856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivistatus_t HwModule::addInputProfile(String8 name, const audio_config_t *config, 109112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie audio_devices_t device, 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 12556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivistatus_t HwModule::removeInputProfile(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; 157cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie Vector <sp<AudioPort> > sources = route->getSources(); 158cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie for (size_t i = 0; i < sources.size(); i++) { 159cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie if (sources[i]->getType() == AUDIO_PORT_TYPE_DEVICE) { 160cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie sourceDevices.add(mDeclaredDevices.getDeviceFromTagName(sources[i]->getTagName())); 161cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 162cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 163cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie return sourceDevices; 164cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie} 165cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie 166cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffievoid HwModule::setRoutes(const AudioRouteVector &routes) 167cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie{ 168cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie mRoutes = routes; 169cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie // Now updating the streams (aka IOProfile until now) supported devices 170cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie refreshSupportedDevices(); 171cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie} 172cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie 173cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffievoid HwModule::refreshSupportedDevices() 174cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie{ 175cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie // Now updating the streams (aka IOProfile until now) supported devices 176cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie for (size_t i = 0; i < mInputProfiles.size(); i++) { 177cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie sp<IOProfile> stream = mInputProfiles[i]; 178cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie DeviceVector sourceDevices; 179cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie const AudioRouteVector &routes = stream->getRoutes(); 180cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie for (size_t j = 0; j < routes.size(); j++) { 181cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie sp<AudioPort> sink = routes[j]->getSink(); 182cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie if (sink == 0 || stream != sink) { 183cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie ALOGE("%s: Invalid route attached to input stream", __FUNCTION__); 184cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie continue; 185cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 186cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie DeviceVector sourceDevicesForRoute = getRouteSourceDevices(routes[j]); 187cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie if (sourceDevicesForRoute.isEmpty()) { 188cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie ALOGE("%s: invalid source devices for %s", __FUNCTION__, stream->getName().string()); 189cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie continue; 190cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 191cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie sourceDevices.add(sourceDevicesForRoute); 192cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 193cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie if (sourceDevices.isEmpty()) { 194cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie ALOGE("%s: invalid source devices for %s", __FUNCTION__, stream->getName().string()); 195cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie continue; 196cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 197cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie stream->setSupportedDevices(sourceDevices); 198cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 199cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie for (size_t i = 0; i < mOutputProfiles.size(); i++) { 200cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie sp<IOProfile> stream = mOutputProfiles[i]; 201cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie DeviceVector sinkDevices; 202cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie const AudioRouteVector &routes = stream->getRoutes(); 203cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie for (size_t j = 0; j < routes.size(); j++) { 204cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie sp<AudioPort> source = routes[j]->getSources().findByTagName(stream->getTagName()); 205cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie if (source == 0 || stream != source) { 206cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie ALOGE("%s: Invalid route attached to output stream", __FUNCTION__); 207cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie continue; 208cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 209cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie sp<DeviceDescriptor> sinkDevice = getRouteSinkDevice(routes[j]); 210cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie if (sinkDevice == 0) { 211cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie ALOGE("%s: invalid sink device for %s", __FUNCTION__, stream->getName().string()); 212cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie continue; 213cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 214cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie sinkDevices.add(sinkDevice); 215cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 216cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie stream->setSupportedDevices(sinkDevices); 217cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie } 218cbb3044d6bfa9ab30c83b67874f40344e29805e1François Gaffie} 21956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 22056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid HwModule::dump(int fd) 22156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 22256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi const size_t SIZE = 256; 22356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi char buffer[SIZE]; 22456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi String8 result; 22556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 226a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie snprintf(buffer, SIZE, " - name: %s\n", getName()); 22756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 22856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " - handle: %d\n", mHandle); 22956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 23056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " - version: %u.%u\n", mHalVersion >> 8, mHalVersion & 0xFF); 23156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 23256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, result.string(), result.size()); 23356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (mOutputProfiles.size()) { 23456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, " - outputs:\n", strlen(" - outputs:\n")); 23556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (size_t i = 0; i < mOutputProfiles.size(); i++) { 23656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " output %zu:\n", i); 23756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, buffer, strlen(buffer)); 23856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mOutputProfiles[i]->dump(fd); 23956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 24056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 24156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (mInputProfiles.size()) { 24256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, " - inputs:\n", strlen(" - inputs:\n")); 24356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (size_t i = 0; i < mInputProfiles.size(); i++) { 24456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " input %zu:\n", i); 24556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, buffer, strlen(buffer)); 24656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mInputProfiles[i]->dump(fd); 24756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 24856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 249112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie mDeclaredDevices.dump(fd, String8("Declared"), 2, true); 250f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie mRoutes.dump(fd, 2); 25156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 25256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 25353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffiesp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const 25453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 25553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie sp <HwModule> module; 25653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 25753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) 25853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie { 259a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie if (strcmp(itemAt(i)->getName(), name) == 0) { 26053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return itemAt(i); 26153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 26253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 26353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return module; 26453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 26553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 26653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 26753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffiesp <HwModule> HwModuleCollection::getModuleForDevice(audio_devices_t device) const 26853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 26953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie sp <HwModule> module; 27053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 27153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 272a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie if (itemAt(i)->getHandle() == 0) { 27353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie continue; 27453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 27553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (audio_is_output_device(device)) { 27653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t j = 0; j < itemAt(i)->mOutputProfiles.size(); j++) 27753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie { 278a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie if (itemAt(i)->mOutputProfiles[j]->supportDevice(device)) { 27953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return itemAt(i); 28053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 28153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 28253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } else { 28353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t j = 0; j < itemAt(i)->mInputProfiles.size(); j++) { 284a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie if (itemAt(i)->mInputProfiles[j]->supportDevice(device)) { 28553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return itemAt(i); 28653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 28753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 28853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 28953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 29053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return module; 29153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 29253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 29353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffiesp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices_t device, 29453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie const char *device_address, 295634b71478742310960f3fdb4241e70a0735712c4Eric Laurent const char *device_name, 296634b71478742310960f3fdb4241e70a0735712c4Eric Laurent bool matchAdress) const 29753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 29853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie String8 address = (device_address == NULL) ? String8("") : String8(device_address); 29953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie // handle legacy remote submix case where the address was not always specified 30053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (device_distinguishes_on_address(device) && (address.length() == 0)) { 30153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie address = String8("0"); 30253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 30353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 30453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 30553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie const sp<HwModule> hwModule = itemAt(i); 30653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (hwModule->mHandle == 0) { 30753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie continue; 30853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 309634b71478742310960f3fdb4241e70a0735712c4Eric Laurent DeviceVector declaredDevices = hwModule->getDeclaredDevices(); 310634b71478742310960f3fdb4241e70a0735712c4Eric Laurent DeviceVector deviceList = declaredDevices.getDevicesFromTypeAddr(device, address); 31153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (!deviceList.isEmpty()) { 31253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return deviceList.itemAt(0); 31353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 314634b71478742310960f3fdb4241e70a0735712c4Eric Laurent if (!matchAdress) { 315634b71478742310960f3fdb4241e70a0735712c4Eric Laurent deviceList = declaredDevices.getDevicesFromType(device); 316634b71478742310960f3fdb4241e70a0735712c4Eric Laurent if (!deviceList.isEmpty()) { 317634b71478742310960f3fdb4241e70a0735712c4Eric Laurent return deviceList.itemAt(0); 318634b71478742310960f3fdb4241e70a0735712c4Eric Laurent } 319634b71478742310960f3fdb4241e70a0735712c4Eric Laurent } 32053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 32153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 3221d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois Gaffie sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device); 3231d4481fb9cb1ea149f79f2a5d22110af84fbc90bFrançois Gaffie devDesc->setName(String8(device_name)); 32453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie devDesc->mAddress = address; 32553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return devDesc; 32653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 32753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 32853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffiestatus_t HwModuleCollection::dump(int fd) const 32953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 33053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie const size_t SIZE = 256; 33153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie char buffer[SIZE]; 33253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 33353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie snprintf(buffer, SIZE, "\nHW Modules dump:\n"); 33453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie write(fd, buffer, strlen(buffer)); 33553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 33653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1); 33753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie write(fd, buffer, strlen(buffer)); 33853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie itemAt(i)->dump(fd); 33953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 34053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return NO_ERROR; 34153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 34253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 34356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} //namespace android 344