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

Commit 1630f24b authored by Mikhail Naganov's avatar Mikhail Naganov Committed by Android (Google) Code Review
Browse files

Merge changes from topic "cherrypicker-L47600000963081744:N22400001405878786" into udc-qpr-dev

* changes:
  libaudiohal@aidl: Fix handling of point-to-point connections
  libaudiohal@aidl: Handle postponed streams closing
  Fix the format used by ThreadBase::toAudioPortConfig
  audioflinger: Clear InputSource in RecordThread::clearInput
  libaudiohal@aidl: Fix port config matching in findOrCreatePortConfig
  libaudiohal@aidl: Log clarifications
  Add AIDL union tag checking before access
  libaudiohal@aidl: Fix `setPortConfigFromConfig` for unspecified values
  audio: change volume only if effect updates the volume
parents 8bb76cf2 b695746f
Loading
Loading
Loading
Loading
+62 −25
Original line number Original line Diff line number Diff line
@@ -21,9 +21,9 @@
#include <set>
#include <set>


#include <gtest/gtest.h>
#include <gtest/gtest.h>
#include <log/log.h>
#include <media/AidlConversionCppNdk.h>
#include <media/AidlConversionCppNdk.h>
#include <media/IAudioFlinger.h>
#include <media/IAudioFlinger.h>
#include <utils/Log.h>


#include "audio_test_utils.h"
#include "audio_test_utils.h"


@@ -277,23 +277,30 @@ TEST_F(AudioSystemTest, CreateAndReleaseAudioPatch) {
        GTEST_SKIP() << "No output devices returned by the audio system";
        GTEST_SKIP() << "No output devices returned by the audio system";
    }
    }


    bool sourceFound = false, sinkFound = false;
    for (const auto& port : ports) {
    for (const auto& port : ports) {
        if (port.role == AUDIO_PORT_ROLE_SOURCE && port.type == AUDIO_PORT_TYPE_DEVICE) {
        if (port.role == AUDIO_PORT_ROLE_SOURCE && port.type == AUDIO_PORT_TYPE_DEVICE) {
            sourcePort = port;
            sourcePort = port;
            sourceFound = true;
        }
        }
        if (port.role == AUDIO_PORT_ROLE_SINK && port.type == AUDIO_PORT_TYPE_DEVICE &&
        if (port.role == AUDIO_PORT_ROLE_SINK && port.type == AUDIO_PORT_TYPE_DEVICE &&
            port.ext.device.type == AUDIO_DEVICE_OUT_SPEAKER) {
            port.ext.device.type == AUDIO_DEVICE_OUT_SPEAKER) {
            sinkPort = port;
            sinkPort = port;
            sinkFound = true;
        }
        if (sourceFound && sinkFound) break;
    }
    }
    if (!sourceFound || !sinkFound) {
        GTEST_SKIP() << "No ports suitable for testing";
    }
    }


    audioPatch.sources[0] = sourcePort.active_config;
    audioPatch.sources[0] = sourcePort.active_config;
    audioPatch.sinks[0] = sinkPort.active_config;
    audioPatch.sinks[0] = sinkPort.active_config;


    status = AudioSystem::createAudioPatch(&audioPatch, &audioPatchHandle);
    status = AudioSystem::createAudioPatch(&audioPatch, &audioPatchHandle);
    EXPECT_EQ(OK, status) << "AudioSystem::createAudiopatch failed between source "
    EXPECT_EQ(OK, status) << "AudioSystem::createAudioPatch failed between source "
                          << sourcePort.ext.device.address << " and sink "
                          << audio_device_to_string(sourcePort.ext.device.type) << " and sink "
                          << sinkPort.ext.device.address;
                          << audio_device_to_string(sinkPort.ext.device.type);


    // verify that patch is established between source and the sink.
    // verify that patch is established between source and the sink.
    ASSERT_NO_FATAL_FAILURE(anyPatchContainsInputDevice(sourcePort.id, patchFound));
    ASSERT_NO_FATAL_FAILURE(anyPatchContainsInputDevice(sourcePort.id, patchFound));
@@ -302,8 +309,8 @@ TEST_F(AudioSystemTest, CreateAndReleaseAudioPatch) {
    EXPECT_NE(AUDIO_PORT_HANDLE_NONE, audioPatchHandle);
    EXPECT_NE(AUDIO_PORT_HANDLE_NONE, audioPatchHandle);
    status = AudioSystem::releaseAudioPatch(audioPatchHandle);
    status = AudioSystem::releaseAudioPatch(audioPatchHandle);
    EXPECT_EQ(OK, status) << "AudioSystem::releaseAudioPatch failed between source "
    EXPECT_EQ(OK, status) << "AudioSystem::releaseAudioPatch failed between source "
                          << sourcePort.ext.device.address << " and sink "
                          << audio_device_to_string(sourcePort.ext.device.type) << " and sink "
                          << sinkPort.ext.device.address;
                          << audio_device_to_string(sinkPort.ext.device.type);


    // verify that no patch is established between source and the sink after releaseAudioPatch.
    // verify that no patch is established between source and the sink after releaseAudioPatch.
    ASSERT_NO_FATAL_FAILURE(anyPatchContainsInputDevice(sourcePort.id, patchFound));
    ASSERT_NO_FATAL_FAILURE(anyPatchContainsInputDevice(sourcePort.id, patchFound));
@@ -608,10 +615,18 @@ class WithSimulatedDeviceConnections {


android::media::audio::common::AudioPort GenerateUniqueDeviceAddress(
android::media::audio::common::AudioPort GenerateUniqueDeviceAddress(
        const android::media::audio::common::AudioPort& port) {
        const android::media::audio::common::AudioPort& port) {
    // Point-to-point connections do not use addresses.
    static const std::set<std::string> kPointToPointConnections = {
            AudioDeviceDescription::CONNECTION_ANALOG(), AudioDeviceDescription::CONNECTION_HDMI(),
            AudioDeviceDescription::CONNECTION_HDMI_ARC(),
            AudioDeviceDescription::CONNECTION_HDMI_EARC(),
            AudioDeviceDescription::CONNECTION_SPDIF()};
    static int nextId = 0;
    static int nextId = 0;
    using Tag = AudioDeviceAddress::Tag;
    using Tag = AudioDeviceAddress::Tag;
    const auto& deviceDescription = port.ext.get<AudioPortExt::Tag::device>().device.type;
    AudioDeviceAddress address;
    AudioDeviceAddress address;
    switch (suggestDeviceAddressTag(port.ext.get<AudioPortExt::Tag::device>().device.type)) {
    if (kPointToPointConnections.count(deviceDescription.connection) == 0) {
        switch (suggestDeviceAddressTag(deviceDescription)) {
            case Tag::id:
            case Tag::id:
                address = AudioDeviceAddress::make<Tag::id>(std::to_string(++nextId));
                address = AudioDeviceAddress::make<Tag::id>(std::to_string(++nextId));
                break;
                break;
@@ -631,6 +646,7 @@ android::media::audio::common::AudioPort GenerateUniqueDeviceAddress(
                address = AudioDeviceAddress::make<Tag::alsa>(std::vector<int32_t>{1, ++nextId});
                address = AudioDeviceAddress::make<Tag::alsa>(std::vector<int32_t>{1, ++nextId});
                break;
                break;
        }
        }
    }
    android::media::audio::common::AudioPort result = port;
    android::media::audio::common::AudioPort result = port;
    result.ext.get<AudioPortExt::Tag::device>().device.address = std::move(address);
    result.ext.get<AudioPortExt::Tag::device>().device.address = std::move(address);
    return result;
    return result;
@@ -689,3 +705,24 @@ TEST_F(AudioSystemTest, SetDeviceConnectedState) {
        EXPECT_EQ(AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, deviceState);
        EXPECT_EQ(AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, deviceState);
    }
    }
}
}

class TestExecutionTracer : public ::testing::EmptyTestEventListener {
  public:
    void OnTestStart(const ::testing::TestInfo& test_info) override {
        TraceTestState("Started", test_info);
    }
    void OnTestEnd(const ::testing::TestInfo& test_info) override {
        TraceTestState("Completed", test_info);
    }

  private:
    static void TraceTestState(const std::string& state, const ::testing::TestInfo& test_info) {
        ALOGI("%s %s::%s", state.c_str(), test_info.test_suite_name(), test_info.name());
    }
};

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
    return RUN_ALL_TESTS();
}
+111 −22
Original line number Original line Diff line number Diff line
@@ -42,6 +42,7 @@ using aidl::android::media::audio::common::AudioConfig;
using aidl::android::media::audio::common::AudioDevice;
using aidl::android::media::audio::common::AudioDevice;
using aidl::android::media::audio::common::AudioDeviceAddress;
using aidl::android::media::audio::common::AudioDeviceAddress;
using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioFormatDescription;
using aidl::android::media::audio::common::AudioFormatType;
using aidl::android::media::audio::common::AudioFormatType;
using aidl::android::media::audio::common::AudioInputFlags;
using aidl::android::media::audio::common::AudioInputFlags;
using aidl::android::media::audio::common::AudioIoFlags;
using aidl::android::media::audio::common::AudioIoFlags;
@@ -97,10 +98,16 @@ void setConfigFromPortConfig(AudioConfig* config, const AudioPortConfig& portCon
}
}


void setPortConfigFromConfig(AudioPortConfig* portConfig, const AudioConfig& config) {
void setPortConfigFromConfig(AudioPortConfig* portConfig, const AudioConfig& config) {
    if (config.base.sampleRate != 0) {
        portConfig->sampleRate = Int{ .value = config.base.sampleRate };
        portConfig->sampleRate = Int{ .value = config.base.sampleRate };
    }
    if (config.base.channelMask != AudioChannelLayout{}) {
        portConfig->channelMask = config.base.channelMask;
        portConfig->channelMask = config.base.channelMask;
    }
    if (config.base.format != AudioFormatDescription{}) {
        portConfig->format = config.base.format;
        portConfig->format = config.base.format;
    }
    }
}


// Note: these converters are for types defined in different AIDL files. Although these
// 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
// AIDL files are copies of each other, however formally these are different types
@@ -706,7 +713,11 @@ status_t DeviceHalAidl::createAudioPatch(unsigned int num_sources,
        aidlPatch.sourcePortConfigIds.clear();
        aidlPatch.sourcePortConfigIds.clear();
        aidlPatch.sinkPortConfigIds.clear();
        aidlPatch.sinkPortConfigIds.clear();
    }
    }
    ALOGD("%s: sources: %s, sinks: %s",
    // The IDs will be found by 'fillPortConfigs', however the original 'aidlSources' and
    // 'aidlSinks' will not be updated because 'setAudioPatch' only needs IDs. Here we log
    // the source arguments, where only the audio configuration and device specifications
    // are relevant.
    ALOGD("%s: [disregard IDs] sources: %s, sinks: %s",
            __func__, ::android::internal::ToString(aidlSources).c_str(),
            __func__, ::android::internal::ToString(aidlSources).c_str(),
            ::android::internal::ToString(aidlSinks).c_str());
            ::android::internal::ToString(aidlSinks).c_str());
    auto fillPortConfigs = [&](
    auto fillPortConfigs = [&](
@@ -1032,11 +1043,12 @@ status_t DeviceHalAidl::prepareToDisconnectExternalDevice(const struct audio_por
    // There is not AIDL API defined for `prepareToDisconnectExternalDevice`.
    // There is not AIDL API defined for `prepareToDisconnectExternalDevice`.
    // Call `setConnectedState` instead.
    // Call `setConnectedState` instead.
    // TODO(b/279824103): call prepareToDisconnectExternalDevice when it is added.
    // TODO(b/279824103): call prepareToDisconnectExternalDevice when it is added.
    const status_t status = setConnectedState(port, false /*connected*/);
    if (const status_t status = setConnectedState(port, false /*connected*/); status == NO_ERROR) {
    if (status == NO_ERROR) {
        mDeviceDisconnectionNotified.insert(port->id);
        mDeviceDisconnectionNotified.insert(port->id);
    }
    }
    return status;
    // Return that there was no error as otherwise the disconnection procedure will not be
    // considered complete for upper layers, and 'setConnectedState' will not be called again.
    return NO_ERROR;
}
}


status_t DeviceHalAidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
status_t DeviceHalAidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
@@ -1069,10 +1081,14 @@ status_t DeviceHalAidl::setConnectedState(const struct audio_port_v7 *port, bool
        matchDevice.address = AudioDeviceAddress::make<AudioDeviceAddress::id>();
        matchDevice.address = AudioDeviceAddress::make<AudioDeviceAddress::id>();
        auto portsIt = findPort(matchDevice);
        auto portsIt = findPort(matchDevice);
        if (portsIt == mPorts.end()) {
        if (portsIt == mPorts.end()) {
            ALOGW("%s: device port for device %s is not found in the module %s",
            // Since 'setConnectedState' is called for all modules, it is normal when the device
                    __func__, matchDevice.toString().c_str(), mInstance.c_str());
            // port not found in every one of them.
            return BAD_VALUE;
            return BAD_VALUE;
        } else {
            ALOGD("%s: device port for device %s found in the module %s",
                    __func__, matchDevice.toString().c_str(), mInstance.c_str());
        }
        }
        resetUnusedPatchesAndPortConfigs();
        // Use the ID of the "template" port, use all the information from the provided port.
        // Use the ID of the "template" port, use all the information from the provided port.
        aidlPort.id = portsIt->first;
        aidlPort.id = portsIt->first;
        AudioPort connectedPort;
        AudioPort connectedPort;
@@ -1083,20 +1099,32 @@ status_t DeviceHalAidl::setConnectedState(const struct audio_port_v7 *port, bool
                "%s: module %s, duplicate port ID received from HAL: %s, existing port: %s",
                "%s: module %s, duplicate port ID received from HAL: %s, existing port: %s",
                __func__, mInstance.c_str(), connectedPort.toString().c_str(),
                __func__, mInstance.c_str(), connectedPort.toString().c_str(),
                it->second.toString().c_str());
                it->second.toString().c_str());
        mConnectedPorts[connectedPort.id] = false;
    } else {  // !connected
    } else {  // !connected
        AudioDevice matchDevice = aidlPort.ext.get<AudioPortExt::device>().device;
        AudioDevice matchDevice = aidlPort.ext.get<AudioPortExt::device>().device;
        auto portsIt = findPort(matchDevice);
        auto portsIt = findPort(matchDevice);
        if (portsIt == mPorts.end()) {
        if (portsIt == mPorts.end()) {
            ALOGW("%s: device port for device %s is not found in the module %s",
            // Since 'setConnectedState' is called for all modules, it is normal when the device
                    __func__, matchDevice.toString().c_str(), mInstance.c_str());
            // port not found in every one of them.
            return BAD_VALUE;
            return BAD_VALUE;
        } else {
            ALOGD("%s: device port for device %s found in the module %s",
                    __func__, matchDevice.toString().c_str(), mInstance.c_str());
        }
        }
        // Any streams opened on the external device must be closed by this time,
        // thus we can clean up patches and port configs that were created for them.
        resetUnusedPatchesAndPortConfigs();
        resetUnusedPatchesAndPortConfigs();
        RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mModule->disconnectExternalDevice(
        // Streams are closed by AudioFlinger independently from device disconnections.
                                portsIt->second.id)));
        // It is possible that the stream has not been closed yet.
        const int32_t portId = portsIt->second.id;
        if (!isPortHeldByAStream(portId)) {
            RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
                            mModule->disconnectExternalDevice(portId)));
            mPorts.erase(portsIt);
            mPorts.erase(portsIt);
            mConnectedPorts.erase(portId);
        } else {
            ALOGD("%s: since device port ID %d is used by a stream, "
                    "external device disconnection postponed", __func__, portId);
            mConnectedPorts[portId] = true;
        }
    }
    }
    return updateRoutes();
    return updateRoutes();
}
}
@@ -1104,6 +1132,7 @@ status_t DeviceHalAidl::setConnectedState(const struct audio_port_v7 *port, bool
status_t DeviceHalAidl::setSimulateDeviceConnections(bool enabled) {
status_t DeviceHalAidl::setSimulateDeviceConnections(bool enabled) {
    TIME_CHECK();
    TIME_CHECK();
    if (!mModule) return NO_INIT;
    if (!mModule) return NO_INIT;
    resetUnusedPatchesAndPortConfigs();
    ModuleDebug debug{ .simulateDeviceConnections = enabled };
    ModuleDebug debug{ .simulateDeviceConnections = enabled };
    status_t status = statusTFromBinderStatus(mModule->setModuleDebug(debug));
    status_t status = statusTFromBinderStatus(mModule->setModuleDebug(debug));
    // This is important to log as it affects HAL behavior.
    // This is important to log as it affects HAL behavior.
@@ -1518,7 +1547,7 @@ status_t DeviceHalAidl::findOrCreatePortConfig(
        }
        }
        RETURN_STATUS_IF_ERROR(createOrUpdatePortConfig(requestedPortConfig, &portConfigIt,
        RETURN_STATUS_IF_ERROR(createOrUpdatePortConfig(requestedPortConfig, &portConfigIt,
                created));
                created));
    } else if (!flags.has_value()) {
    } else if (portConfigIt == mPortConfigs.end() && !flags.has_value()) {
        ALOGW("%s: mix port config for %s, handle %d not found in the module %s, "
        ALOGW("%s: mix port config for %s, handle %d not found in the module %s, "
                "and was not created as flags are not specified",
                "and was not created as flags are not specified",
                __func__, config.toString().c_str(), ioHandle, mInstance.c_str());
                __func__, config.toString().c_str(), ioHandle, mInstance.c_str());
@@ -1593,9 +1622,26 @@ DeviceHalAidl::Ports::iterator DeviceHalAidl::findPort(const AudioDevice& device
    } else if (device.type.type == AudioDeviceType::OUT_DEFAULT) {
    } else if (device.type.type == AudioDeviceType::OUT_DEFAULT) {
        return mPorts.find(mDefaultOutputPortId);
        return mPorts.find(mDefaultOutputPortId);
    }
    }
    if (device.address.getTag() != AudioDeviceAddress::id ||
            !device.address.get<AudioDeviceAddress::id>().empty()) {
        return std::find_if(mPorts.begin(), mPorts.end(),
        return std::find_if(mPorts.begin(), mPorts.end(),
                [&](const auto& pair) { return audioDeviceMatches(device, pair.second); });
                [&](const auto& pair) { return audioDeviceMatches(device, pair.second); });
    }
    }
    // For connection w/o an address, two ports can be found: the template port,
    // and a connected port (if exists). Make sure we return the connected port.
    DeviceHalAidl::Ports::iterator portIt = mPorts.end();
    for (auto it = mPorts.begin(); it != mPorts.end(); ++it) {
        if (audioDeviceMatches(device, it->second)) {
            if (mConnectedPorts.find(it->first) != mConnectedPorts.end()) {
                return it;
            } else {
                // Will return 'it' if there is no connected port.
                portIt = it;
            }
        }
    }
    return portIt;
}


DeviceHalAidl::Ports::iterator DeviceHalAidl::findPort(
DeviceHalAidl::Ports::iterator DeviceHalAidl::findPort(
            const AudioConfig& config, const AudioIoFlags& flags,
            const AudioConfig& config, const AudioIoFlags& flags,
@@ -1672,6 +1718,28 @@ DeviceHalAidl::PortConfigs::iterator DeviceHalAidl::findPortConfig(
                        p.ext.template get<Tag::mix>().handle == ioHandle; });
                        p.ext.template get<Tag::mix>().handle == ioHandle; });
}
}


bool DeviceHalAidl::isPortHeldByAStream(int32_t portId) {
    // It is assumed that mStreams has already been cleaned up.
    for (const auto& streamPair : mStreams) {
        int32_t patchId = streamPair.second;
        auto patchIt = mPatches.find(patchId);
        if (patchIt == mPatches.end()) continue;
        for (int32_t id : patchIt->second.sourcePortConfigIds) {
            auto portConfigIt = mPortConfigs.find(id);
            if (portConfigIt != mPortConfigs.end() && portConfigIt->second.portId == portId) {
                return true;
            }
        }
        for (int32_t id : patchIt->second.sinkPortConfigIds) {
            auto portConfigIt = mPortConfigs.find(id);
            if (portConfigIt != mPortConfigs.end() && portConfigIt->second.portId == portId) {
                return true;
            }
        }
    }
    return false;
}

void DeviceHalAidl::resetPatch(int32_t patchId) {
void DeviceHalAidl::resetPatch(int32_t patchId) {
    if (auto it = mPatches.find(patchId); it != mPatches.end()) {
    if (auto it = mPatches.find(patchId); it != mPatches.end()) {
        mPatches.erase(it);
        mPatches.erase(it);
@@ -1721,10 +1789,10 @@ void DeviceHalAidl::resetUnusedPortConfigs() {
    // The assumption is that port configs are used to create patches
    // The assumption is that port configs are used to create patches
    // (or to open streams, but that involves creation of patches, too). Thus,
    // (or to open streams, but that involves creation of patches, too). Thus,
    // orphaned port configs can and should be reset.
    // orphaned port configs can and should be reset.
    std::set<int32_t> portConfigIds;
    std::map<int32_t, int32_t /*portID*/> portConfigIds;
    std::transform(mPortConfigs.begin(), mPortConfigs.end(),
    std::transform(mPortConfigs.begin(), mPortConfigs.end(),
            std::inserter(portConfigIds, portConfigIds.end()),
            std::inserter(portConfigIds, portConfigIds.end()),
            [](const auto& pcPair) { return pcPair.first; });
            [](const auto& pcPair) { return std::make_pair(pcPair.first, pcPair.second.portId); });
    for (const auto& p : mPatches) {
    for (const auto& p : mPatches) {
        for (int32_t id : p.second.sourcePortConfigIds) portConfigIds.erase(id);
        for (int32_t id : p.second.sourcePortConfigIds) portConfigIds.erase(id);
        for (int32_t id : p.second.sinkPortConfigIds) portConfigIds.erase(id);
        for (int32_t id : p.second.sinkPortConfigIds) portConfigIds.erase(id);
@@ -1732,7 +1800,28 @@ void DeviceHalAidl::resetUnusedPortConfigs() {
    for (int32_t id : mInitialPortConfigIds) {
    for (int32_t id : mInitialPortConfigIds) {
        portConfigIds.erase(id);
        portConfigIds.erase(id);
    }
    }
    for (int32_t id : portConfigIds) resetPortConfig(id);
    std::set<int32_t> retryDeviceDisconnection;
    for (const auto& portConfigAndIdPair : portConfigIds) {
        resetPortConfig(portConfigAndIdPair.first);
        if (const auto it = mConnectedPorts.find(portConfigAndIdPair.second);
                it != mConnectedPorts.end() && it->second) {
            retryDeviceDisconnection.insert(portConfigAndIdPair.second);
        }
    }
    for (int32_t portId : retryDeviceDisconnection) {
        if (!isPortHeldByAStream(portId)) {
            TIME_CHECK();
            if (auto status = mModule->disconnectExternalDevice(portId); status.isOk()) {
                mPorts.erase(portId);
                mConnectedPorts.erase(portId);
                ALOGD("%s: executed postponed external device disconnection for port ID %d",
                        __func__, portId);
            }
        }
    }
    if (!retryDeviceDisconnection.empty()) {
        updateRoutes();
    }
}
}


status_t DeviceHalAidl::updateRoutes() {
status_t DeviceHalAidl::updateRoutes() {
+4 −0
Original line number Original line Diff line number Diff line
@@ -191,6 +191,8 @@ class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl,
        Status status = Status::UNKNOWN;
        Status status = Status::UNKNOWN;
        MicrophoneInfoProvider::Info info;
        MicrophoneInfoProvider::Info info;
    };
    };
    // IDs of ports for connected external devices, and whether they are held by streams.
    using ConnectedPorts = std::map<int32_t /*port ID*/, bool>;
    using Patches = std::map<int32_t /*patch ID*/,
    using Patches = std::map<int32_t /*patch ID*/,
            ::aidl::android::hardware::audio::core::AudioPatch>;
            ::aidl::android::hardware::audio::core::AudioPatch>;
    using PortConfigs = std::map<int32_t /*port config ID*/,
    using PortConfigs = std::map<int32_t /*port config ID*/,
@@ -261,6 +263,7 @@ class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl,
            const ::aidl::android::media::audio::common::AudioConfig& config,
            const ::aidl::android::media::audio::common::AudioConfig& config,
            const std::optional<::aidl::android::media::audio::common::AudioIoFlags>& flags,
            const std::optional<::aidl::android::media::audio::common::AudioIoFlags>& flags,
            int32_t ioHandle);
            int32_t ioHandle);
    bool isPortHeldByAStream(int32_t portId);
    status_t prepareToOpenStream(
    status_t prepareToOpenStream(
        int32_t aidlHandle,
        int32_t aidlHandle,
        const ::aidl::android::media::audio::common::AudioDevice& aidlDevice,
        const ::aidl::android::media::audio::common::AudioDevice& aidlDevice,
@@ -318,6 +321,7 @@ class DeviceHalAidl : public DeviceHalInterface, public ConversionHelperAidl,
    std::mutex mLock;
    std::mutex mLock;
    std::map<void*, Callbacks> mCallbacks GUARDED_BY(mLock);
    std::map<void*, Callbacks> mCallbacks GUARDED_BY(mLock);
    std::set<audio_port_handle_t> mDeviceDisconnectionNotified;
    std::set<audio_port_handle_t> mDeviceDisconnectionNotified;
    ConnectedPorts mConnectedPorts;
};
};


} // namespace android
} // namespace android
+57 −28

File changed.

Preview size limit exceeded, changes collapsed.

+5 −0
Original line number Original line Diff line number Diff line
@@ -72,6 +72,11 @@ class EffectConversionHelperAidl {


    static constexpr int kDefaultframeCount = 0x100;
    static constexpr int kDefaultframeCount = 0x100;


    template <typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
    static inline std::string numericPointerToString(T* pt) {
        return pt ? std::to_string(*pt) : "nullptr";
    }

    using AudioChannelLayout = aidl::android::media::audio::common::AudioChannelLayout;
    using AudioChannelLayout = aidl::android::media::audio::common::AudioChannelLayout;
    const aidl::android::media::audio::common::AudioConfig kDefaultAudioConfig = {
    const aidl::android::media::audio::common::AudioConfig kDefaultAudioConfig = {
            .base = {.sampleRate = 44100,
            .base = {.sampleRate = 44100,
Loading