StreamDescriptor.cpp revision d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4d
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::Volumes"
18//#define LOG_NDEBUG 0
19
20//#define VERY_VERBOSE_LOGGING
21#ifdef VERY_VERBOSE_LOGGING
22#define ALOGVV ALOGV
23#else
24#define ALOGVV(a...) do { } while(0)
25#endif
26
27#include "StreamDescriptor.h"
28#include "Gains.h"
29#include <utils/Log.h>
30#include <utils/String8.h>
31
32namespace android {
33
34// --- StreamDescriptor class implementation
35
36StreamDescriptor::StreamDescriptor()
37    :   mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
38{
39    // Initialize the current stream's index to mIndexMax so volume isn't 0 in
40    // cases where the Java layer doesn't call into the audio policy service to
41    // set the default volume.
42    mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, mIndexMax);
43}
44
45int StreamDescriptor::getVolumeIndex(audio_devices_t device) const
46{
47    device = Volume::getDeviceForVolume(device);
48    // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT
49    if (mIndexCur.indexOfKey(device) < 0) {
50        device = AUDIO_DEVICE_OUT_DEFAULT;
51    }
52    return mIndexCur.valueFor(device);
53}
54
55void StreamDescriptor::clearCurrentVolumeIndex()
56{
57    mIndexCur.clear();
58}
59
60void StreamDescriptor::addCurrentVolumeIndex(audio_devices_t device, int index)
61{
62    mIndexCur.add(device, index);
63}
64
65void StreamDescriptor::setVolumeIndexMin(int volIndexMin)
66{
67    mIndexMin = volIndexMin;
68}
69
70void StreamDescriptor::setVolumeIndexMax(int volIndexMax)
71{
72    mIndexMax = volIndexMax;
73}
74
75void StreamDescriptor::setVolumeCurvePoint(device_category deviceCategory,
76                                           const VolumeCurvePoint *point)
77{
78    mVolumeCurve[deviceCategory] = point;
79}
80
81void StreamDescriptor::dump(int fd) const
82{
83    const size_t SIZE = 256;
84    char buffer[SIZE];
85    String8 result;
86
87    snprintf(buffer, SIZE, "%s         %02d         %02d         ",
88             mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
89    result.append(buffer);
90    for (size_t i = 0; i < mIndexCur.size(); i++) {
91        snprintf(buffer, SIZE, "%04x : %02d, ",
92                 mIndexCur.keyAt(i),
93                 mIndexCur.valueAt(i));
94        result.append(buffer);
95    }
96    result.append("\n");
97
98    write(fd, result.string(), result.size());
99}
100
101StreamDescriptorCollection::StreamDescriptorCollection()
102{
103    for (size_t stream = 0 ; stream < AUDIO_STREAM_CNT; stream++) {
104        add(static_cast<audio_stream_type_t>(stream), StreamDescriptor());
105    }
106}
107
108bool StreamDescriptorCollection::canBeMuted(audio_stream_type_t stream)
109{
110    return valueAt(stream).canBeMuted();
111}
112
113void StreamDescriptorCollection::clearCurrentVolumeIndex(audio_stream_type_t stream)
114{
115    editValueAt(stream).clearCurrentVolumeIndex();
116}
117
118void StreamDescriptorCollection::addCurrentVolumeIndex(audio_stream_type_t stream,
119                                                       audio_devices_t device, int index)
120{
121    editValueAt(stream).addCurrentVolumeIndex(device, index);
122}
123
124void StreamDescriptorCollection::setVolumeCurvePoint(audio_stream_type_t stream,
125                                                     device_category deviceCategory,
126                                                     const VolumeCurvePoint *point)
127{
128    editValueAt(stream).setVolumeCurvePoint(deviceCategory, point);
129}
130
131const VolumeCurvePoint *StreamDescriptorCollection::getVolumeCurvePoint(audio_stream_type_t stream,
132                                                                        device_category deviceCategory) const
133{
134    return valueAt(stream).getVolumeCurvePoint(deviceCategory);
135}
136
137void StreamDescriptorCollection::setVolumeIndexMin(audio_stream_type_t stream,int volIndexMin)
138{
139    return editValueAt(stream).setVolumeIndexMin(volIndexMin);
140}
141
142void StreamDescriptorCollection::setVolumeIndexMax(audio_stream_type_t stream,int volIndexMax)
143{
144    return editValueAt(stream).setVolumeIndexMax(volIndexMax);
145}
146
147float StreamDescriptorCollection::volIndexToDb(audio_stream_type_t stream, device_category category,
148                                               int indexInUi) const
149{
150    const StreamDescriptor &streamDesc = valueAt(stream);
151    return Gains::volIndexToDb(streamDesc.getVolumeCurvePoint(category),
152                               streamDesc.getVolumeIndexMin(), streamDesc.getVolumeIndexMax(),
153                               indexInUi);
154}
155
156status_t StreamDescriptorCollection::initStreamVolume(audio_stream_type_t stream,
157                                                      int indexMin, int indexMax)
158{
159    ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
160    if (indexMin < 0 || indexMin >= indexMax) {
161        ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d",
162              stream , indexMin, indexMax);
163        return BAD_VALUE;
164    }
165    setVolumeIndexMin(stream, indexMin);
166    setVolumeIndexMax(stream, indexMax);
167    return NO_ERROR;
168}
169
170void StreamDescriptorCollection::initializeVolumeCurves(bool isSpeakerDrcEnabled)
171{
172    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
173        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
174            setVolumeCurvePoint(static_cast<audio_stream_type_t>(i),
175                                static_cast<device_category>(j),
176                                Gains::sVolumeProfiles[i][j]);
177        }
178    }
179
180    // Check availability of DRC on speaker path: if available, override some of the speaker curves
181    if (isSpeakerDrcEnabled) {
182        setVolumeCurvePoint(AUDIO_STREAM_SYSTEM, DEVICE_CATEGORY_SPEAKER,
183                            Gains::sDefaultSystemVolumeCurveDrc);
184        setVolumeCurvePoint(AUDIO_STREAM_RING, DEVICE_CATEGORY_SPEAKER,
185                            Gains::sSpeakerSonificationVolumeCurveDrc);
186        setVolumeCurvePoint(AUDIO_STREAM_ALARM, DEVICE_CATEGORY_SPEAKER,
187                            Gains::sSpeakerSonificationVolumeCurveDrc);
188        setVolumeCurvePoint(AUDIO_STREAM_NOTIFICATION, DEVICE_CATEGORY_SPEAKER,
189                            Gains::sSpeakerSonificationVolumeCurveDrc);
190        setVolumeCurvePoint(AUDIO_STREAM_MUSIC, DEVICE_CATEGORY_SPEAKER,
191                            Gains::sSpeakerMediaVolumeCurveDrc);
192        setVolumeCurvePoint(AUDIO_STREAM_ACCESSIBILITY, DEVICE_CATEGORY_SPEAKER,
193                            Gains::sSpeakerMediaVolumeCurveDrc);
194    }
195}
196
197void StreamDescriptorCollection::switchVolumeCurve(audio_stream_type_t streamSrc,
198                                                   audio_stream_type_t streamDst)
199{
200    for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
201        setVolumeCurvePoint(streamDst, static_cast<device_category>(j),
202                            Gains::sVolumeProfiles[streamSrc][j]);
203    }
204}
205
206status_t StreamDescriptorCollection::dump(int fd) const
207{
208    const size_t SIZE = 256;
209    char buffer[SIZE];
210
211    snprintf(buffer, SIZE, "\nStreams dump:\n");
212    write(fd, buffer, strlen(buffer));
213    snprintf(buffer, SIZE,
214             " Stream  Can be muted  Index Min  Index Max  Index Cur [device : index]...\n");
215    write(fd, buffer, strlen(buffer));
216    for (size_t i = 0; i < size(); i++) {
217        snprintf(buffer, SIZE, " %02zu      ", i);
218        write(fd, buffer, strlen(buffer));
219        valueAt(i).dump(fd);
220    }
221
222    return NO_ERROR;
223}
224
225}; // namespace android
226