1f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie/* 2f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * Copyright (C) 2015 The Android Open Source Project 3f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * 4f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * Licensed under the Apache License, Version 2.0 (the "License"); 5f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * you may not use this file except in compliance with the License. 6f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * You may obtain a copy of the License at 7f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * 8f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * http://www.apache.org/licenses/LICENSE-2.0 9f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * 10f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * Unless required by applicable law or agreed to in writing, software 11f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * distributed under the License is distributed on an "AS IS" BASIS, 12f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * See the License for the specific language governing permissions and 14f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * limitations under the License. 15f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie */ 16f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 17f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#pragma once 18f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 19d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#include "IVolumeCurvesCollection.h" 20d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#include <policy.h> 21f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include <hardware/audio.h> 22f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include <utils/RefBase.h> 23f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include <utils/String8.h> 24d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#include <utils/SortedVector.h> 25d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie#include <utils/KeyedVector.h> 26f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include <system/audio.h> 27f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include <cutils/config_utils.h> 28f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include <string> 29f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include <utility> 30f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 31f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffienamespace android { 32f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 33d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffiestruct CurvePoint 34d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie{ 35d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie CurvePoint() {} 36d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie CurvePoint(int index, int attenuationInMb) : 37d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie mIndex(index), mAttenuationInMb(attenuationInMb) {} 38d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie uint32_t mIndex; 39d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie int mAttenuationInMb; 40d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie}; 41d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 42d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffieinline bool operator< (const CurvePoint &lhs, const CurvePoint &rhs) 43d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie{ 44d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return lhs.mIndex < rhs.mIndex; 45d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie} 46f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 471fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent// A volume curve for a given use case and device category 481fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent// It contains of list of points of this curve expressing the attenuation in Millibels for 49d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie// a given volume index from 0 to 100 50f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieclass VolumeCurve : public RefBase 51f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie{ 52f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffiepublic: 53d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie VolumeCurve(device_category device, audio_stream_type_t stream) : 54d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie mDeviceCategory(device), mStreamType(stream) {} 55f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 56f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie device_category getDeviceCategory() const { return mDeviceCategory; } 57d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie audio_stream_type_t getStreamType() const { return mStreamType; } 58d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 59d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie void add(const CurvePoint &point) { mCurvePoints.add(point); } 60d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 61d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie float volIndexToDb(int indexInUi, int volIndexMin, int volIndexMax) const; 62f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 63d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie void dump(int fd) const; 64f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 65f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieprivate: 66d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie SortedVector<CurvePoint> mCurvePoints; 67f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie device_category mDeviceCategory; 68f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie audio_stream_type_t mStreamType; 69f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie}; 70f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 71d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie// Volume Curves for a given use case indexed by device category 72d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffieclass VolumeCurvesForStream : public KeyedVector<device_category, sp<VolumeCurve> > 73d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie{ 74d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffiepublic: 75d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie VolumeCurvesForStream() : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) 76d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 775a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, 0); 78d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 79d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 80d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie sp<VolumeCurve> getCurvesFor(device_category device) const 81d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 82d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie if (indexOfKey(device) < 0) { 83d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return 0; 84d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 85d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return valueFor(device); 86d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 87d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 88d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie int getVolumeIndex(audio_devices_t device) const 89d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 90d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie device = Volume::getDeviceForVolume(device); 915a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME 92d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie if (mIndexCur.indexOfKey(device) < 0) { 935a2b62984c7cecd1761fe272c078dd814c167942Eric Laurent device = AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME; 94d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 95d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return mIndexCur.valueFor(device); 96d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 97d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 98d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie bool canBeMuted() const { return mCanBeMuted; } 99d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie void clearCurrentVolumeIndex() { mIndexCur.clear(); } 100d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie void addCurrentVolumeIndex(audio_devices_t device, int index) { mIndexCur.add(device, index); } 101d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 102d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie void setVolumeIndexMin(int volIndexMin) { mIndexMin = volIndexMin; } 103d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie int getVolumeIndexMin() const { return mIndexMin; } 104d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 105d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie void setVolumeIndexMax(int volIndexMax) { mIndexMax = volIndexMax; } 106d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie int getVolumeIndexMax() const { return mIndexMax; } 107d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 1081fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent bool hasVolumeIndexForDevice(audio_devices_t device) const 1091fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent { 1101fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent device = Volume::getDeviceForVolume(device); 1111fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent return mIndexCur.indexOfKey(device) >= 0; 1121fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent } 1131fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent 114d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie const sp<VolumeCurve> getOriginVolumeCurve(device_category deviceCategory) const 115d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 116d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie ALOG_ASSERT(mOriginVolumeCurves.indexOfKey(deviceCategory) >= 0, "Invalid device category"); 117d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return mOriginVolumeCurves.valueFor(deviceCategory); 118d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 119d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie void setVolumeCurve(device_category deviceCategory, const sp<VolumeCurve> &volumeCurve) 120d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 121d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie ALOG_ASSERT(indexOfKey(deviceCategory) >= 0, "Invalid device category for Volume Curve"); 122d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie replaceValueFor(deviceCategory, volumeCurve); 123d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 124d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 125d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie ssize_t add(const sp<VolumeCurve> &volumeCurve) 126d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 127d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie device_category deviceCategory = volumeCurve->getDeviceCategory(); 128d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie ssize_t index = indexOfKey(deviceCategory); 129d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie if (index < 0) { 130d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie // Keep track of original Volume Curves per device category in order to switch curves. 131d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie mOriginVolumeCurves.add(deviceCategory, volumeCurve); 132d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return KeyedVector::add(deviceCategory, volumeCurve); 133d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 134d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return index; 135d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 136d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 137d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie float volIndexToDb(device_category deviceCat, int indexInUi) const 138d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 139d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return getCurvesFor(deviceCat)->volIndexToDb(indexInUi, mIndexMin, mIndexMax); 140d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 141d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 142d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie void dump(int fd, int spaces, bool curvePoints = false) const; 143d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 144d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffieprivate: 145d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie KeyedVector<device_category, sp<VolumeCurve> > mOriginVolumeCurves; 146d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie KeyedVector<audio_devices_t, int> mIndexCur; /**< current volume index per device. */ 147d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie int mIndexMin; /**< min volume index. */ 148d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie int mIndexMax; /**< max volume index. */ 149d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie bool mCanBeMuted; /**< true is the stream can be muted. */ 150d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie}; 151d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 152d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie// Collection of Volume Curves indexed by use case 153d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffieclass VolumeCurvesCollection : public KeyedVector<audio_stream_type_t, VolumeCurvesForStream>, 154d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie public IVolumeCurvesCollection 155d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie{ 156d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffiepublic: 157d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie VolumeCurvesCollection() 158d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 15919219b44e05555b29e00ce56ce273d168fa83888François Gaffie // Create an empty collection of curves 16019219b44e05555b29e00ce56ce273d168fa83888François Gaffie for (ssize_t i = 0 ; i < AUDIO_STREAM_CNT; i++) { 161d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie audio_stream_type_t stream = static_cast<audio_stream_type_t>(i); 162d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie KeyedVector::add(stream, VolumeCurvesForStream()); 163d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 164d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 165d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 166d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie // Once XML has been parsed, must be call first to sanity check table and initialize indexes 167d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie virtual status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax) 168d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 169d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie editValueAt(stream).setVolumeIndexMin(indexMin); 170d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie editValueAt(stream).setVolumeIndexMax(indexMax); 171d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return NO_ERROR; 172d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 173d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie virtual void clearCurrentVolumeIndex(audio_stream_type_t stream) 174d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 175d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie editCurvesFor(stream).clearCurrentVolumeIndex(); 176d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 177d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie virtual void addCurrentVolumeIndex(audio_stream_type_t stream, audio_devices_t device, int index) 178d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 179d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie editCurvesFor(stream).addCurrentVolumeIndex(device, index); 180d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 181d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie virtual bool canBeMuted(audio_stream_type_t stream) { return getCurvesFor(stream).canBeMuted(); } 182d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 183d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie virtual int getVolumeIndexMin(audio_stream_type_t stream) const 184d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 185d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return getCurvesFor(stream).getVolumeIndexMin(); 186d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 187d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie virtual int getVolumeIndexMax(audio_stream_type_t stream) const 188d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 189d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return getCurvesFor(stream).getVolumeIndexMax(); 190d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 191d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie virtual int getVolumeIndex(audio_stream_type_t stream, audio_devices_t device) 192d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 193d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return getCurvesFor(stream).getVolumeIndex(device); 194d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 195d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie virtual void switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst) 196d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 197d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie const VolumeCurvesForStream &sourceCurves = getCurvesFor(streamSrc); 198d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie VolumeCurvesForStream &dstCurves = editCurvesFor(streamDst); 199d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie ALOG_ASSERT(sourceCurves.size() == dstCurves.size(), "device category not aligned"); 200d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie for (size_t index = 0; index < sourceCurves.size(); index++) { 201d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie device_category cat = sourceCurves.keyAt(index); 202d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie dstCurves.setVolumeCurve(cat, sourceCurves.getOriginVolumeCurve(cat)); 203d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 204d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 205d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie virtual float volIndexToDb(audio_stream_type_t stream, device_category cat, int indexInUi) const 206d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 207d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return getCurvesFor(stream).volIndexToDb(cat, indexInUi); 208d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 2091fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent virtual bool hasVolumeIndexForDevice(audio_stream_type_t stream, 2101fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent audio_devices_t device) const 2111fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent { 2121fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent return getCurvesFor(stream).hasVolumeIndexForDevice(device); 2131fd372e40ef40643fa9d036a0c9db043475b1b02Eric Laurent } 214d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 215d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie virtual status_t dump(int fd) const; 216d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 217d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie ssize_t add(const sp<VolumeCurve> &volumeCurve) 218d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 219d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie audio_stream_type_t streamType = volumeCurve->getStreamType(); 220d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return editCurvesFor(streamType).add(volumeCurve); 221d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 222d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie VolumeCurvesForStream &editCurvesFor(audio_stream_type_t stream) 223d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 224d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie ALOG_ASSERT(indexOfKey(stream) >= 0, "Invalid stream type for Volume Curve"); 225d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return editValueAt(stream); 226d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 227d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie const VolumeCurvesForStream &getCurvesFor(audio_stream_type_t stream) const 228d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie { 229d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie ALOG_ASSERT(indexOfKey(stream) >= 0, "Invalid stream type for Volume Curve"); 230d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return valueFor(stream); 231d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 232d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie}; 233f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 234f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie}; // namespace android 235