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

Commit 2d814898 authored by Mikhail Naganov's avatar Mikhail Naganov Committed by Cherrypicker Worker
Browse files

libaudiohal: Implement retrieval of APM configuration

Add the following interface methods:
 - DevicesFactoryHalInterface::getDeviceNames
 - DevicesFactoryHalInterface::getSurroundSoundConfig
 - DevicesFactoryHalInterface::getEngineConfig
 - DeviceHalInterface::getAudioPorts
 - DeviceHalInterface::getAudioRoutes

These methods are implemented for the AIDL adapter.
The HIDL adapter does not implement them, and this is
how the framework will know that it needs to fall back
to use the XML config.

Bug: 205884982
Test: m
(cherry picked from https://android-review.googlesource.com/q/commit:f83b974f39b7e8ba61d201014d781eccd4c8b09a)
Merged-In: Iaab5dfa00587b5db6c9cb472dcec6a8e3f6417e0
Change-Id: Iaab5dfa00587b5db6c9cb472dcec6a8e3f6417e0
parent bfbb75b8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -300,11 +300,13 @@ aidl_interface {
        "aidl/android/media/AudioPortRole.aidl",
        "aidl/android/media/AudioPortType.aidl",
        "aidl/android/media/AudioProfileSys.aidl",
        "aidl/android/media/AudioRoute.aidl",
        "aidl/android/media/AudioTimestampInternal.aidl",
        "aidl/android/media/AudioUniqueIdUse.aidl",
        "aidl/android/media/AudioVibratorInfo.aidl",
        "aidl/android/media/EffectDescriptor.aidl",
        "aidl/android/media/TrackSecondaryOutputInfo.aidl",
        "aidl/android/media/SurroundSoundConfig.aidl",
    ],
    imports: [
        "android.media.audio.common.types-V2",
+38 −0
Original line number 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;

/**
 * TODO(b/280077672): This is a temporary copy of the stable
 * android.hardware.audio.core.AudioRoute. Interfaces from the Core API do not
 * support the CPP backend. This copy will be removed either by moving the
 * AudioRoute from core to a.m.a.common or by switching the framework internal
 * interfaces to the NDK backend.
 * {@hide}
 */
parcelable AudioRoute {
    /**
     * The list of IDs of source audio ports ('AudioPort.id').
     * There must be at least one source in a valid route and all IDs must be
     * unique.
     */
    int[] sourcePortIds;
    /** The ID of the sink audio port ('AudioPort.id'). */
    int sinkPortId;
    /** If set, only one source can be active, mixing is not supported. */
    boolean isExclusive;
}
+46 −0
Original line number 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;

import android.media.audio.common.AudioFormatDescription;

/**
 * TODO(b/280077672): This is a temporary copy of the stable
 * android.hardware.audio.core.SurroundSoundConfig parcelable.
 * Interfaces from the Core API do not support the CPP backend. This copy will
 * be removed either by moving the AudioRoute from core to a.m.a.common or by
 * switching the framework internal interfaces to the NDK backend.
 * {@hide}
 */
parcelable SurroundSoundConfig {
    parcelable SurroundFormatFamily {
        /**
         * A primaryFormat shall get an entry in the Surround Settings dialog on TV
         * devices. There must be a corresponding Java ENCODING_... constant
         * defined in AudioFormat.java, and a display name defined in
         * AudioFormat.toDisplayName.
         */
        AudioFormatDescription primaryFormat;
        /**
         * List of formats that shall be equivalent to the primaryFormat from the
         * users' point of view and don't need a dedicated Surround Settings
         * dialog entry.
         */
        AudioFormatDescription[] subFormats;
    }
    SurroundFormatFamily[] formatFamilies;
}
+31 −6
Original line number Diff line number Diff line
@@ -95,8 +95,35 @@ void setPortConfigFromConfig(AudioPortConfig* portConfig, const AudioConfig& con
    portConfig->format = config.base.format;
}

// Note: these converters are for types defined in different AIDL files. Although these
// AIDL files are copies of each other, however formally these are different types
// thus we don't use a conversion via a parcelable.
ConversionResult<media::AudioRoute> ndk2cpp_AudioRoute(const AudioRoute& ndk) {
    media::AudioRoute cpp;
    cpp.sourcePortIds.insert(
            cpp.sourcePortIds.end(), ndk.sourcePortIds.begin(), ndk.sourcePortIds.end());
    cpp.sinkPortId = ndk.sinkPortId;
    cpp.isExclusive = ndk.isExclusive;
    return cpp;
}

}  // namespace

status_t DeviceHalAidl::getAudioPorts(std::vector<media::audio::common::AudioPort> *ports) {
    auto convertAudioPortFromMap = [](const Ports::value_type& pair) {
        return ndk2cpp_AudioPort(pair.second);
    };
    return ::aidl::android::convertRange(mPorts.begin(), mPorts.end(), ports->begin(),
            convertAudioPortFromMap);
}

status_t DeviceHalAidl::getAudioRoutes(std::vector<media::AudioRoute> *routes) {
    *routes = VALUE_OR_RETURN_STATUS(
            ::aidl::android::convertContainer<std::vector<media::AudioRoute>>(
                    mRoutes, ndk2cpp_AudioRoute));
    return OK;
}

status_t DeviceHalAidl::getSupportedDevices(uint32_t*) {
    // Obsolete.
    return INVALID_OPERATION;
@@ -106,8 +133,7 @@ status_t DeviceHalAidl::initCheck() {
    TIME_CHECK();
    if (mModule == nullptr) return NO_INIT;
    std::vector<AudioPort> ports;
    RETURN_STATUS_IF_ERROR(
            statusTFromBinderStatus(mModule->getAudioPorts(&ports)));
    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->getAudioPorts(&ports)));
    ALOGW_IF(ports.empty(), "%s: module %s returned an empty list of audio ports",
            __func__, mInstance.c_str());
    std::transform(ports.begin(), ports.end(), std::inserter(mPorts, mPorts.end()),
@@ -1331,13 +1357,12 @@ void DeviceHalAidl::resetUnusedPortConfigs() {

status_t DeviceHalAidl::updateRoutes() {
    TIME_CHECK();
    std::vector<AudioRoute> routes;
    RETURN_STATUS_IF_ERROR(
            statusTFromBinderStatus(mModule->getAudioRoutes(&routes)));
    ALOGW_IF(routes.empty(), "%s: module %s returned an empty list of audio routes",
            statusTFromBinderStatus(mModule->getAudioRoutes(&mRoutes)));
    ALOGW_IF(mRoutes.empty(), "%s: module %s returned an empty list of audio routes",
            __func__, mInstance.c_str());
    mRoutingMatrix.clear();
    for (const auto& r : routes) {
    for (const auto& r : mRoutes) {
        for (auto portId : r.sourcePortIds) {
            mRoutingMatrix.emplace(r.sinkPortId, portId);
            mRoutingMatrix.emplace(portId, r.sinkPortId);
+6 −0
Original line number Diff line number Diff line
@@ -69,6 +69,10 @@ class MicrophoneInfoProvider : public virtual RefBase {
class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl,
                      public CallbackBroker, public MicrophoneInfoProvider {
  public:
    status_t getAudioPorts(std::vector<media::audio::common::AudioPort> *ports) override;

    status_t getAudioRoutes(std::vector<media::AudioRoute> *routes) override;

    // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
    status_t getSupportedDevices(uint32_t *devices) override;

@@ -185,6 +189,7 @@ class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl,
    using PortConfigs = std::map<int32_t /*port config ID*/,
            ::aidl::android::media::audio::common::AudioPortConfig>;
    using Ports = std::map<int32_t /*port ID*/, ::aidl::android::media::audio::common::AudioPort>;
    using Routes = std::vector<::aidl::android::hardware::audio::core::AudioRoute>;
    // Answers the question "whether portID 'first' is reachable from portID 'second'?"
    // It's not a map because both portIDs are known. The matrix is symmetric.
    using RoutingMatrix = std::set<std::pair<int32_t, int32_t>>;
@@ -287,6 +292,7 @@ class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl,
    PortConfigs mPortConfigs;
    std::set<int32_t> mInitialPortConfigIds;
    Patches mPatches;
    Routes mRoutes;
    RoutingMatrix mRoutingMatrix;
    Streams mStreams;
    Microphones mMicrophones;
Loading