110548295023bee99108e418499aff09fe578211eMikhail Naganov/*
210548295023bee99108e418499aff09fe578211eMikhail Naganov * Copyright (C) 2016 The Android Open Source Project
310548295023bee99108e418499aff09fe578211eMikhail Naganov *
410548295023bee99108e418499aff09fe578211eMikhail Naganov * Licensed under the Apache License, Version 2.0 (the "License");
510548295023bee99108e418499aff09fe578211eMikhail Naganov * you may not use this file except in compliance with the License.
610548295023bee99108e418499aff09fe578211eMikhail Naganov * You may obtain a copy of the License at
710548295023bee99108e418499aff09fe578211eMikhail Naganov *
810548295023bee99108e418499aff09fe578211eMikhail Naganov *      http://www.apache.org/licenses/LICENSE-2.0
910548295023bee99108e418499aff09fe578211eMikhail Naganov *
1010548295023bee99108e418499aff09fe578211eMikhail Naganov * Unless required by applicable law or agreed to in writing, software
1110548295023bee99108e418499aff09fe578211eMikhail Naganov * distributed under the License is distributed on an "AS IS" BASIS,
1210548295023bee99108e418499aff09fe578211eMikhail Naganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1310548295023bee99108e418499aff09fe578211eMikhail Naganov * See the License for the specific language governing permissions and
1410548295023bee99108e418499aff09fe578211eMikhail Naganov * limitations under the License.
1510548295023bee99108e418499aff09fe578211eMikhail Naganov */
1610548295023bee99108e418499aff09fe578211eMikhail Naganov
17e9e4e16564c2949960bf9dd3ab49c9dee2273f3cKevin Rocard#include <common/all-versions/IncludeGuard.h>
185ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#include <core/all-versions/default/Conversions.h>
195ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#include <system/audio.h>
2010548295023bee99108e418499aff09fe578211eMikhail Naganov
2110548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace android {
2210548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace hardware {
2310548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace audio {
24e9e4e16564c2949960bf9dd3ab49c9dee2273f3cKevin Rocardnamespace AUDIO_HAL_VERSION {
2510548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace implementation {
2610548295023bee99108e418499aff09fe578211eMikhail Naganov
271a7432375b8c4a83315ecbd60bcf19f5e0d56be1Kevin Rocard/** Converts a status_t in Result according to the rules of AudioParameter::get*
281a7432375b8c4a83315ecbd60bcf19f5e0d56be1Kevin Rocard * Note: Static method and not private method to avoid leaking status_t dependency
291a7432375b8c4a83315ecbd60bcf19f5e0d56be1Kevin Rocard */
30fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocardstatic Result getHalStatusToResult(status_t status) {
31fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard    switch (status) {
32fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard        case OK:
33fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard            return Result::OK;
34fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard        case BAD_VALUE:  // Nothing was returned, probably because the HAL does
35fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard                         // not handle it
36fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard            return Result::NOT_SUPPORTED;
37fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard        case INVALID_OPERATION:  // Conversion from string to the requested type
38fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard                                 // failed
39fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard            return Result::INVALID_ARGUMENTS;
40fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard        default:  // Should not happen
41fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard            ALOGW("Unexpected status returned by getParam: %u", status);
42fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard            return Result::INVALID_ARGUMENTS;
43fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard    }
44fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard}
45fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard
4610548295023bee99108e418499aff09fe578211eMikhail NaganovResult ParametersUtil::getParam(const char* name, bool* value) {
4710548295023bee99108e418499aff09fe578211eMikhail Naganov    String8 halValue;
4810548295023bee99108e418499aff09fe578211eMikhail Naganov    Result retval = getParam(name, &halValue);
4910548295023bee99108e418499aff09fe578211eMikhail Naganov    *value = false;
5010548295023bee99108e418499aff09fe578211eMikhail Naganov    if (retval == Result::OK) {
51fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard        if (halValue.empty()) {
52fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard            return Result::NOT_SUPPORTED;
53fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard        }
5410548295023bee99108e418499aff09fe578211eMikhail Naganov        *value = !(halValue == AudioParameter::valueOff);
5510548295023bee99108e418499aff09fe578211eMikhail Naganov    }
5610548295023bee99108e418499aff09fe578211eMikhail Naganov    return retval;
5710548295023bee99108e418499aff09fe578211eMikhail Naganov}
5810548295023bee99108e418499aff09fe578211eMikhail Naganov
5910548295023bee99108e418499aff09fe578211eMikhail NaganovResult ParametersUtil::getParam(const char* name, int* value) {
6010548295023bee99108e418499aff09fe578211eMikhail Naganov    const String8 halName(name);
6110548295023bee99108e418499aff09fe578211eMikhail Naganov    AudioParameter keys;
6210548295023bee99108e418499aff09fe578211eMikhail Naganov    keys.addKey(halName);
6310548295023bee99108e418499aff09fe578211eMikhail Naganov    std::unique_ptr<AudioParameter> params = getParams(keys);
64fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard    return getHalStatusToResult(params->getInt(halName, *value));
6510548295023bee99108e418499aff09fe578211eMikhail Naganov}
6610548295023bee99108e418499aff09fe578211eMikhail Naganov
675ec293316e7ea1f768161695a113e50b0ea41d45Kevin RocardResult ParametersUtil::getParam(const char* name, String8* value, AudioParameter context) {
6810548295023bee99108e418499aff09fe578211eMikhail Naganov    const String8 halName(name);
695ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard    context.addKey(halName);
705ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard    std::unique_ptr<AudioParameter> params = getParams(context);
71fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard    return getHalStatusToResult(params->get(halName, *value));
7210548295023bee99108e418499aff09fe578211eMikhail Naganov}
7310548295023bee99108e418499aff09fe578211eMikhail Naganov
7410548295023bee99108e418499aff09fe578211eMikhail Naganovvoid ParametersUtil::getParametersImpl(
755ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard    const hidl_vec<ParameterValue>& context, const hidl_vec<hidl_string>& keys,
7682cb03632c15976838407c231fd85804de9bf84cKevin Rocard    std::function<void(Result retval, const hidl_vec<ParameterValue>& parameters)> cb) {
7710548295023bee99108e418499aff09fe578211eMikhail Naganov    AudioParameter halKeys;
785ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard    for (auto& pair : context) {
795ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard        halKeys.add(String8(pair.key.c_str()), String8(pair.value.c_str()));
805ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard    }
8110548295023bee99108e418499aff09fe578211eMikhail Naganov    for (size_t i = 0; i < keys.size(); ++i) {
8210548295023bee99108e418499aff09fe578211eMikhail Naganov        halKeys.addKey(String8(keys[i].c_str()));
8310548295023bee99108e418499aff09fe578211eMikhail Naganov    }
8410548295023bee99108e418499aff09fe578211eMikhail Naganov    std::unique_ptr<AudioParameter> halValues = getParams(halKeys);
8582cb03632c15976838407c231fd85804de9bf84cKevin Rocard    Result retval =
8682cb03632c15976838407c231fd85804de9bf84cKevin Rocard        (keys.size() == 0 || halValues->size() != 0) ? Result::OK : Result::NOT_SUPPORTED;
8710548295023bee99108e418499aff09fe578211eMikhail Naganov    hidl_vec<ParameterValue> result;
88fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard    result.resize(halValues->size());
89fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard    String8 halKey, halValue;
90fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard    for (size_t i = 0; i < halValues->size(); ++i) {
91fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard        status_t status = halValues->getAt(i, halKey, halValue);
92fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard        if (status != OK) {
93fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard            result.resize(0);
94fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard            retval = getHalStatusToResult(status);
95fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard            break;
9610548295023bee99108e418499aff09fe578211eMikhail Naganov        }
97fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard        result[i].key = halKey.string();
98fa3b4a9334ac3c747c121652441f402a1bd3f45eKevin Rocard        result[i].value = halValue.string();
9910548295023bee99108e418499aff09fe578211eMikhail Naganov    }
10010548295023bee99108e418499aff09fe578211eMikhail Naganov    cb(retval, result);
10110548295023bee99108e418499aff09fe578211eMikhail Naganov}
10210548295023bee99108e418499aff09fe578211eMikhail Naganov
10382cb03632c15976838407c231fd85804de9bf84cKevin Rocardstd::unique_ptr<AudioParameter> ParametersUtil::getParams(const AudioParameter& keys) {
10410548295023bee99108e418499aff09fe578211eMikhail Naganov    String8 paramsAndValues;
10572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard    char* halValues = halGetParameters(keys.keysToString().string());
10610548295023bee99108e418499aff09fe578211eMikhail Naganov    if (halValues != NULL) {
10710548295023bee99108e418499aff09fe578211eMikhail Naganov        paramsAndValues.setTo(halValues);
10810548295023bee99108e418499aff09fe578211eMikhail Naganov        free(halValues);
10910548295023bee99108e418499aff09fe578211eMikhail Naganov    } else {
11010548295023bee99108e418499aff09fe578211eMikhail Naganov        paramsAndValues.clear();
11110548295023bee99108e418499aff09fe578211eMikhail Naganov    }
11210548295023bee99108e418499aff09fe578211eMikhail Naganov    return std::unique_ptr<AudioParameter>(new AudioParameter(paramsAndValues));
11310548295023bee99108e418499aff09fe578211eMikhail Naganov}
11410548295023bee99108e418499aff09fe578211eMikhail Naganov
115912bd4bf2ff9397c40df18c29406af4579b07921Kevin RocardResult ParametersUtil::setParam(const char* name, const char* value) {
116912bd4bf2ff9397c40df18c29406af4579b07921Kevin Rocard    AudioParameter param;
117912bd4bf2ff9397c40df18c29406af4579b07921Kevin Rocard    param.add(String8(name), String8(value));
118912bd4bf2ff9397c40df18c29406af4579b07921Kevin Rocard    return setParams(param);
119912bd4bf2ff9397c40df18c29406af4579b07921Kevin Rocard}
120912bd4bf2ff9397c40df18c29406af4579b07921Kevin Rocard
12110548295023bee99108e418499aff09fe578211eMikhail NaganovResult ParametersUtil::setParam(const char* name, bool value) {
12210548295023bee99108e418499aff09fe578211eMikhail Naganov    AudioParameter param;
12382cb03632c15976838407c231fd85804de9bf84cKevin Rocard    param.add(String8(name), String8(value ? AudioParameter::valueOn : AudioParameter::valueOff));
12410548295023bee99108e418499aff09fe578211eMikhail Naganov    return setParams(param);
12510548295023bee99108e418499aff09fe578211eMikhail Naganov}
12610548295023bee99108e418499aff09fe578211eMikhail Naganov
12710548295023bee99108e418499aff09fe578211eMikhail NaganovResult ParametersUtil::setParam(const char* name, int value) {
12810548295023bee99108e418499aff09fe578211eMikhail Naganov    AudioParameter param;
12910548295023bee99108e418499aff09fe578211eMikhail Naganov    param.addInt(String8(name), value);
13010548295023bee99108e418499aff09fe578211eMikhail Naganov    return setParams(param);
13110548295023bee99108e418499aff09fe578211eMikhail Naganov}
13210548295023bee99108e418499aff09fe578211eMikhail Naganov
1335ec293316e7ea1f768161695a113e50b0ea41d45Kevin RocardResult ParametersUtil::setParam(const char* name, float value) {
13410548295023bee99108e418499aff09fe578211eMikhail Naganov    AudioParameter param;
1355ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard    param.addFloat(String8(name), value);
13610548295023bee99108e418499aff09fe578211eMikhail Naganov    return setParams(param);
13710548295023bee99108e418499aff09fe578211eMikhail Naganov}
13810548295023bee99108e418499aff09fe578211eMikhail Naganov
1395ec293316e7ea1f768161695a113e50b0ea41d45Kevin RocardResult ParametersUtil::setParametersImpl(const hidl_vec<ParameterValue>& context,
1405ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard                                         const hidl_vec<ParameterValue>& parameters) {
14110548295023bee99108e418499aff09fe578211eMikhail Naganov    AudioParameter params;
1425ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard    for (auto& pair : context) {
1435ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard        params.add(String8(pair.key.c_str()), String8(pair.value.c_str()));
1445ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard    }
14510548295023bee99108e418499aff09fe578211eMikhail Naganov    for (size_t i = 0; i < parameters.size(); ++i) {
14682cb03632c15976838407c231fd85804de9bf84cKevin Rocard        params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str()));
14710548295023bee99108e418499aff09fe578211eMikhail Naganov    }
14810548295023bee99108e418499aff09fe578211eMikhail Naganov    return setParams(params);
14910548295023bee99108e418499aff09fe578211eMikhail Naganov}
1505ec293316e7ea1f768161695a113e50b0ea41d45Kevin RocardResult ParametersUtil::setParam(const char* name, const DeviceAddress& address) {
1515ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard    AudioParameter params(String8(deviceAddressToHal(address).c_str()));
1525ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard    params.addInt(String8(name), int(address.device));
1535ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard    return setParams(params);
1545ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard}
15510548295023bee99108e418499aff09fe578211eMikhail Naganov
15610548295023bee99108e418499aff09fe578211eMikhail NaganovResult ParametersUtil::setParams(const AudioParameter& param) {
15710548295023bee99108e418499aff09fe578211eMikhail Naganov    int halStatus = halSetParameters(param.toString().string());
158fba21730f8b4dd7c6919aa3267b3fbdffdeda8a4Kevin Rocard    return util::analyzeStatus(halStatus);
15910548295023bee99108e418499aff09fe578211eMikhail Naganov}
16010548295023bee99108e418499aff09fe578211eMikhail Naganov
16110548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace implementation
162e9e4e16564c2949960bf9dd3ab49c9dee2273f3cKevin Rocard}  // namespace AUDIO_HAL_VERSION
16310548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace audio
16410548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace hardware
16510548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace android
166