HwModule.cpp revision 112b0af826aeca45855690b9c105b2cdf9938bbe
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::HwModule" 18//#define LOG_NDEBUG 0 19 20#include "HwModule.h" 21#include "IOProfile.h" 22#include "AudioGain.h" 23#include <hardware/audio.h> 24#include <policy.h> 25 26namespace android { 27 28HwModule::HwModule(const char *name, uint32_t halVersion) 29 : mName(String8(name)), 30 mHandle(0), 31 mHalVersion(halVersion) 32{ 33} 34 35HwModule::~HwModule() 36{ 37 for (size_t i = 0; i < mOutputProfiles.size(); i++) { 38 mOutputProfiles[i]->clearSupportedDevices(); 39 } 40 for (size_t i = 0; i < mInputProfiles.size(); i++) { 41 mInputProfiles[i]->clearSupportedDevices(); 42 } 43} 44 45status_t HwModule::addOutputProfile(String8 name, const audio_config_t *config, 46 audio_devices_t device, String8 address) 47{ 48 sp<IOProfile> profile = new OutputProfile(name); 49 50 profile->addAudioProfile(new AudioProfile(config->format, config->channel_mask, 51 config->sample_rate)); 52 53 sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device); 54 devDesc->mAddress = address; 55 profile->addSupportedDevice(devDesc); 56 57 return addOutputProfile(profile); 58} 59 60status_t HwModule::addOutputProfile(const sp<IOProfile> &profile) 61{ 62 profile->attach(this); 63 mOutputProfiles.add(profile); 64 return NO_ERROR; 65} 66 67status_t HwModule::addInputProfile(const sp<IOProfile> &profile) 68{ 69 profile->attach(this); 70 mInputProfiles.add(profile); 71 return NO_ERROR; 72} 73 74status_t HwModule::addProfile(const sp<IOProfile> &profile) 75{ 76 switch (profile->getRole()) { 77 case AUDIO_PORT_ROLE_SOURCE: 78 return addOutputProfile(profile); 79 case AUDIO_PORT_ROLE_SINK: 80 return addInputProfile(profile); 81 case AUDIO_PORT_ROLE_NONE: 82 return BAD_VALUE; 83 } 84 return BAD_VALUE; 85} 86 87void HwModule::setProfiles(const IOProfileCollection &profiles) 88{ 89 for (size_t i = 0; i < profiles.size(); i++) { 90 addProfile(profiles[i]); 91 } 92} 93 94status_t HwModule::removeOutputProfile(String8 name) 95{ 96 for (size_t i = 0; i < mOutputProfiles.size(); i++) { 97 if (mOutputProfiles[i]->getName() == name) { 98 mOutputProfiles.removeAt(i); 99 break; 100 } 101 } 102 103 return NO_ERROR; 104} 105 106status_t HwModule::addInputProfile(String8 name, const audio_config_t *config, 107 audio_devices_t device, String8 address) 108{ 109 sp<IOProfile> profile = new InputProfile(name); 110 profile->addAudioProfile(new AudioProfile(config->format, config->channel_mask, 111 config->sample_rate)); 112 113 sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device); 114 devDesc->mAddress = address; 115 profile->addSupportedDevice(devDesc); 116 117 ALOGV("addInputProfile() name %s rate %d mask 0x%08x", 118 name.string(), config->sample_rate, config->channel_mask); 119 120 return addInputProfile(profile); 121} 122 123status_t HwModule::removeInputProfile(String8 name) 124{ 125 for (size_t i = 0; i < mInputProfiles.size(); i++) { 126 if (mInputProfiles[i]->getName() == name) { 127 mInputProfiles.removeAt(i); 128 break; 129 } 130 } 131 132 return NO_ERROR; 133} 134 135 136void HwModule::dump(int fd) 137{ 138 const size_t SIZE = 256; 139 char buffer[SIZE]; 140 String8 result; 141 142 snprintf(buffer, SIZE, " - name: %s\n", getName()); 143 result.append(buffer); 144 snprintf(buffer, SIZE, " - handle: %d\n", mHandle); 145 result.append(buffer); 146 snprintf(buffer, SIZE, " - version: %u.%u\n", mHalVersion >> 8, mHalVersion & 0xFF); 147 result.append(buffer); 148 write(fd, result.string(), result.size()); 149 if (mOutputProfiles.size()) { 150 write(fd, " - outputs:\n", strlen(" - outputs:\n")); 151 for (size_t i = 0; i < mOutputProfiles.size(); i++) { 152 snprintf(buffer, SIZE, " output %zu:\n", i); 153 write(fd, buffer, strlen(buffer)); 154 mOutputProfiles[i]->dump(fd); 155 } 156 } 157 if (mInputProfiles.size()) { 158 write(fd, " - inputs:\n", strlen(" - inputs:\n")); 159 for (size_t i = 0; i < mInputProfiles.size(); i++) { 160 snprintf(buffer, SIZE, " input %zu:\n", i); 161 write(fd, buffer, strlen(buffer)); 162 mInputProfiles[i]->dump(fd); 163 } 164 } 165 mDeclaredDevices.dump(fd, String8("Declared"), 2, true); 166} 167 168sp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const 169{ 170 sp <HwModule> module; 171 172 for (size_t i = 0; i < size(); i++) 173 { 174 if (strcmp(itemAt(i)->getName(), name) == 0) { 175 return itemAt(i); 176 } 177 } 178 return module; 179} 180 181 182sp <HwModule> HwModuleCollection::getModuleForDevice(audio_devices_t device) const 183{ 184 sp <HwModule> module; 185 186 for (size_t i = 0; i < size(); i++) { 187 if (itemAt(i)->getHandle() == 0) { 188 continue; 189 } 190 if (audio_is_output_device(device)) { 191 for (size_t j = 0; j < itemAt(i)->mOutputProfiles.size(); j++) 192 { 193 if (itemAt(i)->mOutputProfiles[j]->supportDevice(device)) { 194 return itemAt(i); 195 } 196 } 197 } else { 198 for (size_t j = 0; j < itemAt(i)->mInputProfiles.size(); j++) { 199 if (itemAt(i)->mInputProfiles[j]->supportDevice(device)) { 200 return itemAt(i); 201 } 202 } 203 } 204 } 205 return module; 206} 207 208sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices_t device, 209 const char *device_address, 210 const char *device_name) const 211{ 212 String8 address = (device_address == NULL) ? String8("") : String8(device_address); 213 // handle legacy remote submix case where the address was not always specified 214 if (device_distinguishes_on_address(device) && (address.length() == 0)) { 215 address = String8("0"); 216 } 217 218 for (size_t i = 0; i < size(); i++) { 219 const sp<HwModule> hwModule = itemAt(i); 220 if (hwModule->mHandle == 0) { 221 continue; 222 } 223 DeviceVector deviceList = 224 hwModule->getDeclaredDevices().getDevicesFromTypeAddr(device, address); 225 if (!deviceList.isEmpty()) { 226 return deviceList.itemAt(0); 227 } 228 deviceList = hwModule->getDeclaredDevices().getDevicesFromType(device); 229 if (!deviceList.isEmpty()) { 230 return deviceList.itemAt(0); 231 } 232 } 233 234 sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device); 235 devDesc->setName(String8(device_name)); 236 devDesc->mAddress = address; 237 return devDesc; 238} 239 240status_t HwModuleCollection::dump(int fd) const 241{ 242 const size_t SIZE = 256; 243 char buffer[SIZE]; 244 245 snprintf(buffer, SIZE, "\nHW Modules dump:\n"); 246 write(fd, buffer, strlen(buffer)); 247 for (size_t i = 0; i < size(); i++) { 248 snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1); 249 write(fd, buffer, strlen(buffer)); 250 itemAt(i)->dump(fd); 251 } 252 return NO_ERROR; 253} 254 255} //namespace android 256