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