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 #pragma once
18 
19 #include "policy.h"
20 #include <Volume.h>
21 #include <system/audio.h>
22 #include <convert/convert.h>
23 #include <utils/Log.h>
24 #include <string>
25 #include <utils/Vector.h>
26 #include <utils/SortedVector.h>
27 
28 namespace android {
29 
30 struct SampleRateTraits
31 {
32     typedef uint32_t Type;
33     typedef SortedVector<Type> Collection;
34 };
35 struct DeviceTraits
36 {
37     typedef audio_devices_t Type;
38     typedef Vector<Type> Collection;
39 };
40 struct OutputFlagTraits
41 {
42     typedef audio_output_flags_t Type;
43     typedef Vector<Type> Collection;
44 };
45 struct InputFlagTraits
46 {
47     typedef audio_input_flags_t Type;
48     typedef Vector<Type> Collection;
49 };
50 struct FormatTraits
51 {
52     typedef audio_format_t Type;
53     typedef Vector<Type> Collection;
54 };
55 struct ChannelTraits
56 {
57     typedef audio_channel_mask_t Type;
58     typedef SortedVector<Type> Collection;
59 };
60 struct OutputChannelTraits : public ChannelTraits {};
61 struct InputChannelTraits : public ChannelTraits {};
62 struct ChannelIndexTraits : public ChannelTraits {};
63 struct GainModeTraits
64 {
65     typedef audio_gain_mode_t Type;
66     typedef Vector<Type> Collection;
67 };
68 struct StreamTraits
69 {
70   typedef audio_stream_type_t Type;
71   typedef Vector<Type> Collection;
72 };
73 struct DeviceCategoryTraits
74 {
75   typedef device_category Type;
76   typedef Vector<Type> Collection;
77 };
78 template <typename T>
79 struct DefaultTraits
80 {
81   typedef T Type;
82   typedef Vector<Type> Collection;
83 };
84 
85 template <class Traits>
86 static void collectionFromString(const std::string &str, typename Traits::Collection &collection,
87                                  const char *del = "|")
88 {
89     char *literal = strdup(str.c_str());
90     for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
91         typename Traits::Type value;
92         if (utilities::convertTo<std::string, typename Traits::Type >(cstr, value)) {
93             collection.add(value);
94         }
95     }
96     free(literal);
97 }
98 
99 template <class Traits>
100 class TypeConverter
101 {
102 public:
103     static bool toString(const typename Traits::Type &value, std::string &str);
104 
105     static bool fromString(const std::string &str, typename Traits::Type &result);
106 
107     static void collectionFromString(const std::string &str,
108                                      typename Traits::Collection &collection,
109                                      const char *del = "|");
110 
111     static uint32_t maskFromString(const std::string &str, const char *del = "|");
112 
113 protected:
114     struct Table {
115         const char *literal;
116         typename Traits::Type value;
117     };
118 
119     static const Table mTable[];
120     static const size_t mSize;
121 };
122 
123 typedef TypeConverter<DeviceTraits> DeviceConverter;
124 typedef TypeConverter<OutputFlagTraits> OutputFlagConverter;
125 typedef TypeConverter<InputFlagTraits> InputFlagConverter;
126 typedef TypeConverter<FormatTraits> FormatConverter;
127 typedef TypeConverter<OutputChannelTraits> OutputChannelConverter;
128 typedef TypeConverter<InputChannelTraits> InputChannelConverter;
129 typedef TypeConverter<ChannelIndexTraits> ChannelIndexConverter;
130 typedef TypeConverter<GainModeTraits> GainModeConverter;
131 typedef TypeConverter<StreamTraits> StreamTypeConverter;
132 typedef TypeConverter<DeviceCategoryTraits> DeviceCategoryConverter;
133 
134 static SampleRateTraits::Collection samplingRatesFromString(const std::string &samplingRates,
135                                                             const char *del = "|")
136 {
137     SampleRateTraits::Collection samplingRateCollection;
138     collectionFromString<SampleRateTraits>(samplingRates, samplingRateCollection, del);
139     return samplingRateCollection;
140 }
141 
142 static FormatTraits::Collection formatsFromString(const std::string &formats, const char *del = "|")
143 {
144     FormatTraits::Collection formatCollection;
145     FormatConverter::collectionFromString(formats, formatCollection, del);
146     return formatCollection;
147 }
148 
formatFromString(const std::string & literalFormat)149 static audio_format_t formatFromString(const std::string &literalFormat)
150 {
151     audio_format_t format;
152     if (literalFormat.empty()) {
153         return gDynamicFormat;
154     }
155     FormatConverter::fromString(literalFormat, format);
156     return format;
157 }
158 
channelMaskFromString(const std::string & literalChannels)159 static audio_channel_mask_t channelMaskFromString(const std::string &literalChannels)
160 {
161     audio_channel_mask_t channels;
162     if (!OutputChannelConverter::fromString(literalChannels, channels) ||
163             !InputChannelConverter::fromString(literalChannels, channels)) {
164         return AUDIO_CHANNEL_INVALID;
165     }
166     return channels;
167 }
168 
169 static ChannelTraits::Collection channelMasksFromString(const std::string &channels,
170                                                         const char *del = "|")
171 {
172     ChannelTraits::Collection channelMaskCollection;
173     OutputChannelConverter::collectionFromString(channels, channelMaskCollection, del);
174     InputChannelConverter::collectionFromString(channels, channelMaskCollection, del);
175     ChannelIndexConverter::collectionFromString(channels, channelMaskCollection, del);
176     return channelMaskCollection;
177 }
178 
179 static InputChannelTraits::Collection inputChannelMasksFromString(const std::string &inChannels,
180                                                                   const char *del = "|")
181 {
182     InputChannelTraits::Collection inputChannelMaskCollection;
183     InputChannelConverter::collectionFromString(inChannels, inputChannelMaskCollection, del);
184     ChannelIndexConverter::collectionFromString(inChannels, inputChannelMaskCollection, del);
185     return inputChannelMaskCollection;
186 }
187 
188 static OutputChannelTraits::Collection outputChannelMasksFromString(const std::string &outChannels,
189                                                                     const char *del = "|")
190 {
191     OutputChannelTraits::Collection outputChannelMaskCollection;
192     OutputChannelConverter::collectionFromString(outChannels, outputChannelMaskCollection, del);
193     ChannelIndexConverter::collectionFromString(outChannels, outputChannelMaskCollection, del);
194     return outputChannelMaskCollection;
195 }
196 
197 }; // namespace android
198 
199