Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9661692 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge changes I8e77238d,Ic4276571 am: 6eaf18b4 am: 19266fc3 am: fad38ca9 am: 2793ae98

parents cc419fa7 2793ae98
Loading
Loading
Loading
Loading
+24 −0
Original line number Original line Diff line number Diff line
@@ -102,3 +102,27 @@ cc_library_headers {
        },
        },
    },
    },
}
}

aidl_interface {
    name: "av-audio-types-aidl",
    unstable: true,
    host_supported: true,
    vendor_available: true,
    double_loadable: true,
    local_include_dir: "aidl",
    srcs: [
        "aidl/android/media/audio/IHalAdapterVendorExtension.aidl",
    ],
    imports: [
        "android.hardware.audio.core-V1",
    ],
    backend: {
        // The C++ backend is disabled transitively due to use of FMQ by the audio core HAL.
        cpp: {
            enabled: false,
        },
        java: {
            sdk_version: "module_current",
        },
    },
}
+136 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media.audio;

import android.hardware.audio.core.VendorParameter;

/**
 * This interface is used by the HAL adapter of the Audio Server. Implementation
 * is optional. Vendors may provide an implementation on the system_ext
 * partition. The default instance of this interface, if provided, must be
 * registered prior to the moment when the audio server connects to HAL modules.
 *
 * {@hide}
 */
interface IHalAdapterVendorExtension {
    enum ParameterScope {
        MODULE = 0,
        STREAM = 1,
    }

    /**
     * Parse raw parameter keys into vendor parameter ids.
     *
     * This method prepares arguments for a call to the 'getVendorParameters'
     * method of an 'IModule' or an 'IStreamCommon' interface instance,
     * depending on the provided scope.
     *
     * The client calls this method in order to prepare arguments for a call to
     * the particular Core HAL interface. The result returned by the HAL is then
     * processed using the 'processVendorParameters' method. It is not required
     * to maintain a 1:1 correspondence between the provided raw keys and the
     * elements of the parsed result. If the returned list is empty, the call of
     * 'getVendorParameters' is skipped. The implementation can either ignore
     * keys which it does not recognize, or throw an error. The latter is
     * preferred as it can help in discovering malformed key names.
     *
     * @param scope The scope of all raw parameter keys.
     * @param rawKeys Raw parameter keys, joined into a string using a semicolon
     *                (';') as the delimiter.
     * @return A list of vendor parameter IDs, see android.hardware.audio.core.VendorParameter.
     * @throws EX_ILLEGAL_ARGUMENT If the implementation can not parse the raw keys
     *                             and prefers to signal an error.
     */
    @utf8InCpp String[] parseVendorParameterIds(
            ParameterScope scope, in @utf8InCpp String rawKeys);

    /**
     * Parse raw parameter key-value pairs into vendor parameters.
     *
     * This method prepares arguments for a call to the 'setVendorParameters'
     * method of an 'IModule' or an 'IStreamCommon' interface instance,
     * depending on the provided scope.
     *
     * The vendor parameters returned using 'syncParameters' argument is then
     * used to call the 'setVendorParameters' method with 'async = false', and
     * 'asyncParameters' is used in a subsequent call to the same method, but
     * with 'async = true'. It is not required to maintain a 1:1 correspondence
     * between the provided key-value pairs and the elements of parsed
     * results. If any of the returned lists of vendor parameters is empty, then
     * the corresponding call is skipped. The implementation can either ignore
     * keys which it does not recognize, and invalid values, or throw an
     * error. The latter is preferred as it can help in discovering malformed
     * key names and values.
     *
     * @param scope The scope of all raw key-value pairs.
     * @param rawKeys Raw key-value pairs, separated by the "equals" sign ('='),
     *                joined into a string using a semicolon (';') as the delimiter.
     * @param syncParameters A list of vendor parameters to be set synchronously.
     * @param asyncParameters A list of vendor parameters to be set asynchronously.
     * @throws EX_ILLEGAL_ARGUMENT If the implementation can not parse raw key-value
     *                             pairs and prefers to signal an error.
     */
    void parseVendorParameters(
            ParameterScope scope, in @utf8InCpp String rawKeysAndValues,
            out VendorParameter[] syncParameters, out VendorParameter[] asyncParameters);

    /**
     * Parse raw value of the parameter for BT A2DP reconfiguration.
     *
     * This method may return any number of vendor parameters (including zero)
     * which will be passed to the 'IBluetoothA2dp.reconfigureOffload' method.
     *
     * @param rawValue An unparsed value of the legacy parameter.
     * @return A list of vendor parameters.
     * @throws EX_ILLEGAL_ARGUMENT If the implementation can not parse the raw value.
     */
    VendorParameter[] parseBluetoothA2dpReconfigureOffload(in @utf8InCpp String rawValue);

    /**
     * Parse raw value of the parameter for BT LE reconfiguration.
     *
     * This method may return any number of vendor parameters (including zero)
     * which will be passed to the 'IBluetoothLe.reconfigureOffload' method.
     *
     * @param rawValue An unparsed value of the legacy parameter.
     * @return A list of vendor parameters.
     * @throws EX_ILLEGAL_ARGUMENT If the implementation can not parse the raw value.
     */
    VendorParameter[] parseBluetoothLeReconfigureOffload(in @utf8InCpp String rawValue);

    /**
     * Process vendor parameters returned by the Audio Core HAL.
     *
     * This processes the result returned from a call to the
     * 'getVendorParameters' method of an 'IModule' or an 'IStreamCommon'
     * interface instance, depending on the provided scope.
     *
     * See 'parseVendorParameterIds' method for the flow description.  It is not
     * required to maintain a 1:1 correspondence between the elements of the
     * provided list and the emitted key-value pairs. The returned string with
     * raw key-value pairs is passed back to the framework.
     *
     * @param scope The scope of vendor parameters.
     * @param parameters Vendor parameters, see android.hardware.audio.core.VendorParameter.
     * @return Key-value pairs, separated by the "equals" sign ('='),
     *         joined into a string using a semicolon (';') as the delimiter.
     * @throws EX_ILLEGAL_ARGUMENT If the implementation can not emit raw key-value
     *                             pairs and prefers to signal an error.
     */
    @utf8InCpp String processVendorParameters(
            ParameterScope scope, in VendorParameter[] parameters);
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,9 @@
          "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__OUTPUT"
          "include-filter": "android.nativemedia.aaudio.AAudioTests#AAudioBasic_TestAAudioBasic_TestBasic_LOW_LATENCY__OUTPUT"
        }
        }
      ]
      ]
    },
    {
      "name": "CoreAudioHalAidlTest"
    }
    }
  ]
  ]
}
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -257,6 +257,7 @@ cc_defaults {
    shared_libs: [
    shared_libs: [
        "android.hardware.common-V2-ndk",
        "android.hardware.common-V2-ndk",
        "android.hardware.common.fmq-V1-ndk",
        "android.hardware.common.fmq-V1-ndk",
        "av-audio-types-aidl-ndk",
        "libaudio_aidl_conversion_common_cpp",
        "libaudio_aidl_conversion_common_cpp",
        "libaudio_aidl_conversion_common_ndk",
        "libaudio_aidl_conversion_common_ndk",
        "libaudio_aidl_conversion_common_ndk_cpp",
        "libaudio_aidl_conversion_common_ndk_cpp",
@@ -315,6 +316,7 @@ cc_library_shared {
filegroup {
filegroup {
    name: "core_audio_hal_aidl_src_files",
    name: "core_audio_hal_aidl_src_files",
    srcs: [
    srcs: [
        "ConversionHelperAidl.cpp",
        "DeviceHalAidl.cpp",
        "DeviceHalAidl.cpp",
        "DevicesFactoryHalAidl.cpp",
        "DevicesFactoryHalAidl.cpp",
        "StreamHalAidl.cpp",
        "StreamHalAidl.cpp",
+125 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "ConversionHelperAidl"

#include <memory>

#include <media/AidlConversionUtil.h>
#include <utils/Log.h>

#include "ConversionHelperAidl.h"

using aidl::android::aidl_utils::statusTFromBinderStatus;
using aidl::android::hardware::audio::core::VendorParameter;
using aidl::android::media::audio::IHalAdapterVendorExtension;

namespace android {

status_t parseAndGetVendorParameters(
        std::shared_ptr<IHalAdapterVendorExtension> vendorExt,
        const VendorParametersRecipient& recipient,
        const AudioParameter& parameterKeys,
        String8* values) {
    using ParameterScope = IHalAdapterVendorExtension::ParameterScope;
    if (parameterKeys.size() == 0) return OK;
    const String8 rawKeys = parameterKeys.keysToString();
    if (vendorExt == nullptr) {
        ALOGW("%s: unknown parameters, ignored: \"%s\"", __func__, rawKeys.c_str());
        return OK;
    }

    std::vector<std::string> parameterIds;
    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(vendorExt->parseVendorParameterIds(
                            ParameterScope(recipient.index()),
                            std::string(rawKeys.c_str()), &parameterIds)));
    if (parameterIds.empty()) return OK;

    std::vector<VendorParameter> parameters;
    if (recipient.index() == static_cast<int>(ParameterScope::MODULE)) {
        auto module = std::get<static_cast<int>(ParameterScope::MODULE)>(recipient);
        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(module->getVendorParameters(
                                parameterIds, &parameters)));
    } else if (recipient.index() == static_cast<int>(ParameterScope::STREAM)) {
        auto stream = std::get<static_cast<int>(ParameterScope::STREAM)>(recipient);
        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(stream->getVendorParameters(
                                parameterIds, &parameters)));
    } else {
        LOG_ALWAYS_FATAL("%s: unexpected recipient variant index: %zu",
                __func__, recipient.index());
    }
    if (!parameters.empty()) {
        std::string vendorParameters;
        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(vendorExt->processVendorParameters(
                                ParameterScope(recipient.index()),
                                parameters, &vendorParameters)));
        // Re-parse the vendor-provided string to ensure that it is correct.
        AudioParameter reparse(String8(vendorParameters.c_str()));
        if (reparse.size() != 0) {
            if (!values->empty()) {
                values->append(";");
            }
            values->append(reparse.toString().c_str());
        }
    }
    return OK;
}

status_t parseAndSetVendorParameters(
        std::shared_ptr<IHalAdapterVendorExtension> vendorExt,
        const VendorParametersRecipient& recipient,
        const AudioParameter& parameters) {
    using ParameterScope = IHalAdapterVendorExtension::ParameterScope;
    if (parameters.size() == 0) return OK;
    const String8 rawKeysAndValues = parameters.toString();
    if (vendorExt == nullptr) {
        ALOGW("%s: unknown parameters, ignored: \"%s\"", __func__, rawKeysAndValues.c_str());
        return OK;
    }

    std::vector<VendorParameter> syncParameters, asyncParameters;
    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(vendorExt->parseVendorParameters(
                            ParameterScope(recipient.index()),
                            std::string(rawKeysAndValues.c_str()),
                            &syncParameters, &asyncParameters)));
    if (recipient.index() == static_cast<int>(ParameterScope::MODULE)) {
        auto module = std::get<static_cast<int>(ParameterScope::MODULE)>(recipient);
        if (!syncParameters.empty()) {
            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(module->setVendorParameters(
                                    syncParameters, false /*async*/)));
        }
        if (!asyncParameters.empty()) {
            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(module->setVendorParameters(
                                    asyncParameters, true /*async*/)));
        }
    } else if (recipient.index() == static_cast<int>(ParameterScope::STREAM)) {
        auto stream = std::get<static_cast<int>(ParameterScope::STREAM)>(recipient);
        if (!syncParameters.empty()) {
            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(stream->setVendorParameters(
                                    syncParameters, false /*async*/)));
        }
        if (!asyncParameters.empty()) {
            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(stream->setVendorParameters(
                                    asyncParameters, true /*async*/)));
        }
    } else {
        LOG_ALWAYS_FATAL("%s: unexpected recipient variant index: %zu",
                __func__, recipient.index());
    }
    return OK;
}

} // namespace android
Loading