| Kevin Rocard | 4bcd67f | 2018-02-28 14:33:38 -0800 | [diff] [blame] | 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 <string.h> | 
|  | 18 |  | 
|  | 19 | #define LOG_TAG "HalHidl" | 
| jiabin | daf4995 | 2019-11-22 14:10:57 -0800 | [diff] [blame] | 20 | #include <media/AudioContainers.h> | 
| Kevin Rocard | 4bcd67f | 2018-02-28 14:33:38 -0800 | [diff] [blame] | 21 | #include <media/AudioParameter.h> | 
|  | 22 | #include <utils/Log.h> | 
|  | 23 |  | 
|  | 24 | #include "ConversionHelperHidl.h" | 
|  | 25 |  | 
| Kevin Rocard | 4bcd67f | 2018-02-28 14:33:38 -0800 | [diff] [blame] | 26 | namespace android { | 
| Kevin Rocard | 070e751 | 2018-05-22 09:29:13 -0700 | [diff] [blame] | 27 | namespace CPP_VERSION { | 
| Kevin Rocard | 4bcd67f | 2018-02-28 14:33:38 -0800 | [diff] [blame] | 28 |  | 
| Mikhail Naganov | 04395fa | 2018-12-14 15:07:26 -0800 | [diff] [blame] | 29 | using namespace ::android::hardware::audio::common::CPP_VERSION; | 
|  | 30 | using namespace ::android::hardware::audio::CPP_VERSION; | 
|  | 31 |  | 
| Kevin Rocard | 4bcd67f | 2018-02-28 14:33:38 -0800 | [diff] [blame] | 32 | // static | 
|  | 33 | status_t ConversionHelperHidl::keysFromHal(const String8& keys, hidl_vec<hidl_string> *hidlKeys) { | 
|  | 34 | AudioParameter halKeys(keys); | 
|  | 35 | if (halKeys.size() == 0) return BAD_VALUE; | 
|  | 36 | hidlKeys->resize(halKeys.size()); | 
|  | 37 | //FIXME:  keyStreamSupportedChannels and keyStreamSupportedSamplingRates come with a | 
|  | 38 | // "keyFormat=<value>" pair. We need to transform it into a single key string so that it is | 
|  | 39 | // carried over to the legacy HAL via HIDL. | 
|  | 40 | String8 value; | 
|  | 41 | bool keepFormatValue = halKeys.size() == 2 && | 
|  | 42 | (halKeys.get(String8(AudioParameter::keyStreamSupportedChannels), value) == NO_ERROR || | 
|  | 43 | halKeys.get(String8(AudioParameter::keyStreamSupportedSamplingRates), value) == NO_ERROR); | 
| jiabin | 1c4794b | 2020-05-05 10:08:05 -0700 | [diff] [blame] | 44 | // When querying encapsulation capabilities, "keyRouting=<value>" pair is used to identify | 
|  | 45 | // the device. We need to transform it into a single key string so that it is carried over to | 
|  | 46 | // the legacy HAL via HIDL. | 
|  | 47 | bool keepRoutingValue = | 
|  | 48 | halKeys.get(String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_MODES), | 
|  | 49 | value) == NO_ERROR || | 
|  | 50 | halKeys.get(String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_METADATA_TYPES), | 
|  | 51 | value) == NO_ERROR; | 
| Kevin Rocard | 4bcd67f | 2018-02-28 14:33:38 -0800 | [diff] [blame] | 52 |  | 
| Kuowei Li | d4adbdb | 2020-08-13 14:44:25 +0800 | [diff] [blame] | 53 | const bool keepDelayValue = | 
|  | 54 | halKeys.get(String8(AudioParameter::keyAdditionalOutputDeviceDelay), | 
|  | 55 | value) == NO_ERROR || | 
|  | 56 | halKeys.get(String8(AudioParameter::keyMaxAdditionalOutputDeviceDelay), | 
|  | 57 | value) == NO_ERROR; | 
|  | 58 |  | 
| Kevin Rocard | 4bcd67f | 2018-02-28 14:33:38 -0800 | [diff] [blame] | 59 | for (size_t i = 0; i < halKeys.size(); ++i) { | 
|  | 60 | String8 key; | 
|  | 61 | status_t status = halKeys.getAt(i, key); | 
|  | 62 | if (status != OK) return status; | 
| jiabin | 1c4794b | 2020-05-05 10:08:05 -0700 | [diff] [blame] | 63 | if ((keepFormatValue && key == AudioParameter::keyFormat) || | 
| Kuowei Li | d4adbdb | 2020-08-13 14:44:25 +0800 | [diff] [blame] | 64 | (keepRoutingValue && key == AudioParameter::keyRouting) || | 
|  | 65 | (keepDelayValue && key == AudioParameter::keyAdditionalOutputDeviceDelay) || | 
|  | 66 | (keepDelayValue && key == AudioParameter::keyMaxAdditionalOutputDeviceDelay)) { | 
| jiabin | 1c4794b | 2020-05-05 10:08:05 -0700 | [diff] [blame] | 67 | AudioParameter keepValueParam; | 
| Kevin Rocard | 4bcd67f | 2018-02-28 14:33:38 -0800 | [diff] [blame] | 68 | halKeys.getAt(i, key, value); | 
| jiabin | 1c4794b | 2020-05-05 10:08:05 -0700 | [diff] [blame] | 69 | keepValueParam.add(key, value); | 
|  | 70 | key = keepValueParam.toString(); | 
| Kevin Rocard | 4bcd67f | 2018-02-28 14:33:38 -0800 | [diff] [blame] | 71 | } | 
|  | 72 | (*hidlKeys)[i] = key.string(); | 
|  | 73 | } | 
|  | 74 | return OK; | 
|  | 75 | } | 
|  | 76 |  | 
|  | 77 | // static | 
|  | 78 | status_t ConversionHelperHidl::parametersFromHal( | 
|  | 79 | const String8& kvPairs, hidl_vec<ParameterValue> *hidlParams) { | 
|  | 80 | AudioParameter params(kvPairs); | 
|  | 81 | if (params.size() == 0) return BAD_VALUE; | 
|  | 82 | hidlParams->resize(params.size()); | 
|  | 83 | for (size_t i = 0; i < params.size(); ++i) { | 
|  | 84 | String8 key, value; | 
|  | 85 | status_t status = params.getAt(i, key, value); | 
|  | 86 | if (status != OK) return status; | 
|  | 87 | (*hidlParams)[i].key = key.string(); | 
|  | 88 | (*hidlParams)[i].value = value.string(); | 
|  | 89 | } | 
|  | 90 | return OK; | 
|  | 91 | } | 
|  | 92 |  | 
|  | 93 | // static | 
|  | 94 | void ConversionHelperHidl::parametersToHal( | 
|  | 95 | const hidl_vec<ParameterValue>& parameters, String8 *values) { | 
|  | 96 | AudioParameter params; | 
|  | 97 | for (size_t i = 0; i < parameters.size(); ++i) { | 
|  | 98 | params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str())); | 
|  | 99 | } | 
|  | 100 | values->setTo(params.toString()); | 
|  | 101 | } | 
|  | 102 |  | 
|  | 103 | ConversionHelperHidl::ConversionHelperHidl(const char* className) | 
|  | 104 | : mClassName(className) { | 
|  | 105 | } | 
|  | 106 |  | 
|  | 107 | // static | 
|  | 108 | status_t ConversionHelperHidl::analyzeResult(const Result& result) { | 
|  | 109 | switch (result) { | 
|  | 110 | case Result::OK: return OK; | 
|  | 111 | case Result::INVALID_ARGUMENTS: return BAD_VALUE; | 
|  | 112 | case Result::INVALID_STATE: return NOT_ENOUGH_DATA; | 
|  | 113 | case Result::NOT_INITIALIZED: return NO_INIT; | 
|  | 114 | case Result::NOT_SUPPORTED: return INVALID_OPERATION; | 
|  | 115 | default: return NO_INIT; | 
|  | 116 | } | 
|  | 117 | } | 
|  | 118 |  | 
|  | 119 | void ConversionHelperHidl::emitError(const char* funcName, const char* description) { | 
|  | 120 | ALOGE("%s %p %s: %s (from rpc)", mClassName, this, funcName, description); | 
|  | 121 | } | 
|  | 122 |  | 
| Kevin Rocard | 070e751 | 2018-05-22 09:29:13 -0700 | [diff] [blame] | 123 | }  // namespace CPP_VERSION | 
| Kevin Rocard | 4bcd67f | 2018-02-28 14:33:38 -0800 | [diff] [blame] | 124 | }  // namespace android |