1 /*
2  * Copyright (C) 2016 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 #include <common/all-versions/IncludeGuard.h>
18 #include <core/all-versions/default/Conversions.h>
19 #include <system/audio.h>
20 
21 namespace android {
22 namespace hardware {
23 namespace audio {
24 namespace AUDIO_HAL_VERSION {
25 namespace implementation {
26 
27 /** Converts a status_t in Result according to the rules of AudioParameter::get*
28  * Note: Static method and not private method to avoid leaking status_t dependency
29  */
getHalStatusToResult(status_t status)30 static Result getHalStatusToResult(status_t status) {
31     switch (status) {
32         case OK:
33             return Result::OK;
34         case BAD_VALUE:  // Nothing was returned, probably because the HAL does
35                          // not handle it
36             return Result::NOT_SUPPORTED;
37         case INVALID_OPERATION:  // Conversion from string to the requested type
38                                  // failed
39             return Result::INVALID_ARGUMENTS;
40         default:  // Should not happen
41             ALOGW("Unexpected status returned by getParam: %u", status);
42             return Result::INVALID_ARGUMENTS;
43     }
44 }
45 
getParam(const char * name,bool * value)46 Result ParametersUtil::getParam(const char* name, bool* value) {
47     String8 halValue;
48     Result retval = getParam(name, &halValue);
49     *value = false;
50     if (retval == Result::OK) {
51         if (halValue.empty()) {
52             return Result::NOT_SUPPORTED;
53         }
54         *value = !(halValue == AudioParameter::valueOff);
55     }
56     return retval;
57 }
58 
getParam(const char * name,int * value)59 Result ParametersUtil::getParam(const char* name, int* value) {
60     const String8 halName(name);
61     AudioParameter keys;
62     keys.addKey(halName);
63     std::unique_ptr<AudioParameter> params = getParams(keys);
64     return getHalStatusToResult(params->getInt(halName, *value));
65 }
66 
getParam(const char * name,String8 * value,AudioParameter context)67 Result ParametersUtil::getParam(const char* name, String8* value, AudioParameter context) {
68     const String8 halName(name);
69     context.addKey(halName);
70     std::unique_ptr<AudioParameter> params = getParams(context);
71     return getHalStatusToResult(params->get(halName, *value));
72 }
73 
getParametersImpl(const hidl_vec<ParameterValue> & context,const hidl_vec<hidl_string> & keys,std::function<void (Result retval,const hidl_vec<ParameterValue> & parameters)> cb)74 void ParametersUtil::getParametersImpl(
75     const hidl_vec<ParameterValue>& context, const hidl_vec<hidl_string>& keys,
76     std::function<void(Result retval, const hidl_vec<ParameterValue>& parameters)> cb) {
77     AudioParameter halKeys;
78     for (auto& pair : context) {
79         halKeys.add(String8(pair.key.c_str()), String8(pair.value.c_str()));
80     }
81     for (size_t i = 0; i < keys.size(); ++i) {
82         halKeys.addKey(String8(keys[i].c_str()));
83     }
84     std::unique_ptr<AudioParameter> halValues = getParams(halKeys);
85     Result retval =
86         (keys.size() == 0 || halValues->size() != 0) ? Result::OK : Result::NOT_SUPPORTED;
87     hidl_vec<ParameterValue> result;
88     result.resize(halValues->size());
89     String8 halKey, halValue;
90     for (size_t i = 0; i < halValues->size(); ++i) {
91         status_t status = halValues->getAt(i, halKey, halValue);
92         if (status != OK) {
93             result.resize(0);
94             retval = getHalStatusToResult(status);
95             break;
96         }
97         result[i].key = halKey.string();
98         result[i].value = halValue.string();
99     }
100     cb(retval, result);
101 }
102 
getParams(const AudioParameter & keys)103 std::unique_ptr<AudioParameter> ParametersUtil::getParams(const AudioParameter& keys) {
104     String8 paramsAndValues;
105     char* halValues = halGetParameters(keys.keysToString().string());
106     if (halValues != NULL) {
107         paramsAndValues.setTo(halValues);
108         free(halValues);
109     } else {
110         paramsAndValues.clear();
111     }
112     return std::unique_ptr<AudioParameter>(new AudioParameter(paramsAndValues));
113 }
114 
setParam(const char * name,const char * value)115 Result ParametersUtil::setParam(const char* name, const char* value) {
116     AudioParameter param;
117     param.add(String8(name), String8(value));
118     return setParams(param);
119 }
120 
setParam(const char * name,bool value)121 Result ParametersUtil::setParam(const char* name, bool value) {
122     AudioParameter param;
123     param.add(String8(name), String8(value ? AudioParameter::valueOn : AudioParameter::valueOff));
124     return setParams(param);
125 }
126 
setParam(const char * name,int value)127 Result ParametersUtil::setParam(const char* name, int value) {
128     AudioParameter param;
129     param.addInt(String8(name), value);
130     return setParams(param);
131 }
132 
setParam(const char * name,float value)133 Result ParametersUtil::setParam(const char* name, float value) {
134     AudioParameter param;
135     param.addFloat(String8(name), value);
136     return setParams(param);
137 }
138 
setParametersImpl(const hidl_vec<ParameterValue> & context,const hidl_vec<ParameterValue> & parameters)139 Result ParametersUtil::setParametersImpl(const hidl_vec<ParameterValue>& context,
140                                          const hidl_vec<ParameterValue>& parameters) {
141     AudioParameter params;
142     for (auto& pair : context) {
143         params.add(String8(pair.key.c_str()), String8(pair.value.c_str()));
144     }
145     for (size_t i = 0; i < parameters.size(); ++i) {
146         params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str()));
147     }
148     return setParams(params);
149 }
setParam(const char * name,const DeviceAddress & address)150 Result ParametersUtil::setParam(const char* name, const DeviceAddress& address) {
151     AudioParameter params(String8(deviceAddressToHal(address).c_str()));
152     params.addInt(String8(name), int(address.device));
153     return setParams(params);
154 }
155 
setParams(const AudioParameter & param)156 Result ParametersUtil::setParams(const AudioParameter& param) {
157     int halStatus = halSetParameters(param.toString().string());
158     return util::analyzeStatus(halStatus);
159 }
160 
161 }  // namespace implementation
162 }  // namespace AUDIO_HAL_VERSION
163 }  // namespace audio
164 }  // namespace hardware
165 }  // namespace android
166