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::EffectDescriptor" 18//#define LOG_NDEBUG 0 19 20#include "EffectDescriptor.h" 21#include <utils/String8.h> 22 23namespace android { 24 25status_t EffectDescriptor::dump(int fd) 26{ 27 const size_t SIZE = 256; 28 char buffer[SIZE]; 29 String8 result; 30 31 snprintf(buffer, SIZE, " I/O: %d\n", mIo); 32 result.append(buffer); 33 snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy); 34 result.append(buffer); 35 snprintf(buffer, SIZE, " Session: %d\n", mSession); 36 result.append(buffer); 37 snprintf(buffer, SIZE, " Name: %s\n", mDesc.name); 38 result.append(buffer); 39 snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled"); 40 result.append(buffer); 41 write(fd, result.string(), result.size()); 42 43 return NO_ERROR; 44} 45 46EffectDescriptorCollection::EffectDescriptorCollection() : 47 mTotalEffectsCpuLoad(0), 48 mTotalEffectsMemory(0), 49 mTotalEffectsMemoryMaxUsed(0) 50{ 51 52} 53 54status_t EffectDescriptorCollection::registerEffect(const effect_descriptor_t *desc, 55 audio_io_handle_t io, 56 uint32_t strategy, 57 int session, 58 int id) 59{ 60 if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) { 61 ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB", 62 desc->name, desc->memoryUsage); 63 return INVALID_OPERATION; 64 } 65 mTotalEffectsMemory += desc->memoryUsage; 66 if (mTotalEffectsMemory > mTotalEffectsMemoryMaxUsed) { 67 mTotalEffectsMemoryMaxUsed = mTotalEffectsMemory; 68 } 69 ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d", 70 desc->name, io, strategy, session, id); 71 ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory); 72 73 sp<EffectDescriptor> effectDesc = new EffectDescriptor(); 74 memcpy (&effectDesc->mDesc, desc, sizeof(effect_descriptor_t)); 75 effectDesc->mIo = io; 76 effectDesc->mStrategy = static_cast<routing_strategy>(strategy); 77 effectDesc->mSession = session; 78 effectDesc->mEnabled = false; 79 80 add(id, effectDesc); 81 82 return NO_ERROR; 83} 84 85status_t EffectDescriptorCollection::unregisterEffect(int id) 86{ 87 ssize_t index = indexOfKey(id); 88 if (index < 0) { 89 ALOGW("unregisterEffect() unknown effect ID %d", id); 90 return INVALID_OPERATION; 91 } 92 93 sp<EffectDescriptor> effectDesc = valueAt(index); 94 95 setEffectEnabled(effectDesc, false); 96 97 if (mTotalEffectsMemory < effectDesc->mDesc.memoryUsage) { 98 ALOGW("unregisterEffect() memory %d too big for total %d", 99 effectDesc->mDesc.memoryUsage, mTotalEffectsMemory); 100 effectDesc->mDesc.memoryUsage = mTotalEffectsMemory; 101 } 102 mTotalEffectsMemory -= effectDesc->mDesc.memoryUsage; 103 ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d", 104 effectDesc->mDesc.name, id, effectDesc->mDesc.memoryUsage, mTotalEffectsMemory); 105 106 removeItem(id); 107 108 return NO_ERROR; 109} 110 111status_t EffectDescriptorCollection::setEffectEnabled(int id, bool enabled) 112{ 113 ssize_t index = indexOfKey(id); 114 if (index < 0) { 115 ALOGW("unregisterEffect() unknown effect ID %d", id); 116 return INVALID_OPERATION; 117 } 118 119 return setEffectEnabled(valueAt(index), enabled); 120} 121 122 123status_t EffectDescriptorCollection::setEffectEnabled(const sp<EffectDescriptor> &effectDesc, 124 bool enabled) 125{ 126 if (enabled == effectDesc->mEnabled) { 127 ALOGV("setEffectEnabled(%s) effect already %s", 128 enabled?"true":"false", enabled?"enabled":"disabled"); 129 return INVALID_OPERATION; 130 } 131 132 if (enabled) { 133 if (mTotalEffectsCpuLoad + effectDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) { 134 ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS", 135 effectDesc->mDesc.name, (float)effectDesc->mDesc.cpuLoad/10); 136 return INVALID_OPERATION; 137 } 138 mTotalEffectsCpuLoad += effectDesc->mDesc.cpuLoad; 139 ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad); 140 } else { 141 if (mTotalEffectsCpuLoad < effectDesc->mDesc.cpuLoad) { 142 ALOGW("setEffectEnabled(false) CPU load %d too high for total %d", 143 effectDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad); 144 effectDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad; 145 } 146 mTotalEffectsCpuLoad -= effectDesc->mDesc.cpuLoad; 147 ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad); 148 } 149 effectDesc->mEnabled = enabled; 150 return NO_ERROR; 151} 152 153bool EffectDescriptorCollection::isNonOffloadableEffectEnabled() 154{ 155 for (size_t i = 0; i < size(); i++) { 156 sp<EffectDescriptor> effectDesc = valueAt(i); 157 if (effectDesc->mEnabled && (effectDesc->mStrategy == STRATEGY_MEDIA) && 158 ((effectDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) { 159 ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d", 160 effectDesc->mDesc.name, effectDesc->mSession); 161 return true; 162 } 163 } 164 return false; 165} 166 167uint32_t EffectDescriptorCollection::getMaxEffectsCpuLoad() const 168{ 169 return MAX_EFFECTS_CPU_LOAD; 170} 171 172uint32_t EffectDescriptorCollection::getMaxEffectsMemory() const 173{ 174 return MAX_EFFECTS_MEMORY; 175} 176 177status_t EffectDescriptorCollection::dump(int fd) 178{ 179 const size_t SIZE = 256; 180 char buffer[SIZE]; 181 182 snprintf(buffer, SIZE, 183 "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB, Max memory used: %d KB\n", 184 (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory, mTotalEffectsMemoryMaxUsed); 185 write(fd, buffer, strlen(buffer)); 186 187 snprintf(buffer, SIZE, "Registered effects:\n"); 188 write(fd, buffer, strlen(buffer)); 189 for (size_t i = 0; i < size(); i++) { 190 snprintf(buffer, SIZE, "- Effect %d dump:\n", keyAt(i)); 191 write(fd, buffer, strlen(buffer)); 192 valueAt(i)->dump(fd); 193 } 194 return NO_ERROR; 195} 196 197}; //namespace android 198