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