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

Commit 4dbb96f6 authored by Shunkai Yao's avatar Shunkai Yao Committed by Gerrit Code Review
Browse files

Merge changes from topic "fix-b-273252382-connect-external-device"

* changes:
  libaudiohal@aidl: Consider routing when finding mix ports
  libaudiohal@aidl: Implement setConnectedState
  Add AudioSystem.listDeclaredDevicePorts method
parents 68362b52 289468a3
Loading
Loading
Loading
Loading
+129 −20
Original line number Original line Diff line number Diff line
@@ -14,6 +14,8 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#include <stdio.h>

#include <algorithm>
#include <algorithm>
#include <map>
#include <map>
#include <utility>
#include <utility>
@@ -570,7 +572,6 @@ const detail::AudioDevicePairs& getAudioDevicePairs() {
                GET_DEVICE_DESC_CONNECTION(BT_LE));
                GET_DEVICE_DESC_CONNECTION(BT_LE));
        return pairs;
        return pairs;
    }();
    }();
#undef GET_DEVICE_DESC_CONNECTION
    return pairs;
    return pairs;
}
}


@@ -998,55 +999,161 @@ ConversionResult<AudioDeviceDescription> legacy2aidl_audio_devices_t_AudioDevice
    }
    }
}
}


AudioDeviceAddress::Tag suggestDeviceAddressTag(const AudioDeviceDescription& description) {
    using Tag = AudioDeviceAddress::Tag;
    if (std::string connection = description.connection;
            connection == GET_DEVICE_DESC_CONNECTION(BT_A2DP) ||
            // Note: BT LE Broadcast uses a "group id".
            (description.type != AudioDeviceType::OUT_BROADCAST &&
                    connection == GET_DEVICE_DESC_CONNECTION(BT_LE)) ||
            connection == GET_DEVICE_DESC_CONNECTION(BT_SCO) ||
            connection == GET_DEVICE_DESC_CONNECTION(WIRELESS)) {
        return Tag::mac;
    } else if (connection == GET_DEVICE_DESC_CONNECTION(IP_V4)) {
        return Tag::ipv4;
    } else if (connection == GET_DEVICE_DESC_CONNECTION(USB)) {
        return Tag::alsa;
    }
    return Tag::id;
}

::android::status_t aidl2legacy_AudioDevice_audio_device(
::android::status_t aidl2legacy_AudioDevice_audio_device(
        const AudioDevice& aidl,
        const AudioDevice& aidl,
        audio_devices_t* legacyType, char* legacyAddress) {
        audio_devices_t* legacyType, char* legacyAddress) {
    *legacyType = VALUE_OR_RETURN_STATUS(
    std::string stringAddress;
            aidl2legacy_AudioDeviceDescription_audio_devices_t(aidl.type));
    RETURN_STATUS_IF_ERROR(aidl2legacy_AudioDevice_audio_device(
    return aidl2legacy_string(
                    aidl, legacyType, &stringAddress));
                    aidl.address.get<AudioDeviceAddress::id>(),
    return aidl2legacy_string(stringAddress, legacyAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN);
                    legacyAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN);
}
}


::android::status_t aidl2legacy_AudioDevice_audio_device(
::android::status_t aidl2legacy_AudioDevice_audio_device(
        const AudioDevice& aidl,
        const AudioDevice& aidl,
        audio_devices_t* legacyType, String8* legacyAddress) {
        audio_devices_t* legacyType, String8* legacyAddress) {
    *legacyType = VALUE_OR_RETURN_STATUS(
    std::string stringAddress;
            aidl2legacy_AudioDeviceDescription_audio_devices_t(aidl.type));
    RETURN_STATUS_IF_ERROR(aidl2legacy_AudioDevice_audio_device(
    *legacyAddress = VALUE_OR_RETURN_STATUS(aidl2legacy_string_view_String8(
                    aidl, legacyType, &stringAddress));
                    aidl.address.get<AudioDeviceAddress::id>()));
    *legacyAddress = VALUE_OR_RETURN_STATUS(aidl2legacy_string_view_String8(stringAddress));
    return OK;
    return OK;
}
}


::android::status_t aidl2legacy_AudioDevice_audio_device(
::android::status_t aidl2legacy_AudioDevice_audio_device(
        const AudioDevice& aidl,
        const AudioDevice& aidl,
        audio_devices_t* legacyType, std::string* legacyAddress) {
        audio_devices_t* legacyType, std::string* legacyAddress) {
    using Tag = AudioDeviceAddress::Tag;
    *legacyType = VALUE_OR_RETURN_STATUS(
    *legacyType = VALUE_OR_RETURN_STATUS(
            aidl2legacy_AudioDeviceDescription_audio_devices_t(aidl.type));
            aidl2legacy_AudioDeviceDescription_audio_devices_t(aidl.type));
    *legacyAddress = aidl.address.get<AudioDeviceAddress::id>();
    char addressBuffer[AUDIO_DEVICE_MAX_ADDRESS_LEN]{};
    // 'aidl.address' can be empty even when the connection type is not.
    // This happens for device ports that act as "blueprints". In this case
    // we pass an empty string using the 'id' variant.
    switch (aidl.address.getTag()) {
        case Tag::mac: {
            const std::vector<uint8_t>& mac = aidl.address.get<AudioDeviceAddress::mac>();
            if (mac.size() != 6) return BAD_VALUE;
            snprintf(addressBuffer, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
                    mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
        } break;
        case Tag::ipv4: {
            const std::vector<uint8_t>& ipv4 = aidl.address.get<AudioDeviceAddress::ipv4>();
            if (ipv4.size() != 4) return BAD_VALUE;
            snprintf(addressBuffer, AUDIO_DEVICE_MAX_ADDRESS_LEN, "%u.%u.%u.%u",
                    ipv4[0], ipv4[1], ipv4[2], ipv4[3]);
        } break;
        case Tag::ipv6: {
            const std::vector<int32_t>& ipv6 = aidl.address.get<AudioDeviceAddress::ipv6>();
            if (ipv6.size() != 8) return BAD_VALUE;
            snprintf(addressBuffer, AUDIO_DEVICE_MAX_ADDRESS_LEN,
                    "%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X",
                    ipv6[0], ipv6[1], ipv6[2], ipv6[3], ipv6[4], ipv6[5], ipv6[6], ipv6[7]);
        } break;
        case Tag::alsa: {
            const std::vector<int32_t>& alsa = aidl.address.get<AudioDeviceAddress::alsa>();
            if (alsa.size() != 2) return BAD_VALUE;
            snprintf(addressBuffer, AUDIO_DEVICE_MAX_ADDRESS_LEN, "card=%d;device=%d",
                    alsa[0], alsa[1]);
        } break;
        case Tag::id: {
            RETURN_STATUS_IF_ERROR(aidl2legacy_string(aidl.address.get<AudioDeviceAddress::id>(),
                            addressBuffer, AUDIO_DEVICE_MAX_ADDRESS_LEN));
        } break;
    }
    *legacyAddress = addressBuffer;
    return OK;
    return OK;
}
}


ConversionResult<AudioDevice> legacy2aidl_audio_device_AudioDevice(
ConversionResult<AudioDevice> legacy2aidl_audio_device_AudioDevice(
        audio_devices_t legacyType, const char* legacyAddress) {
        audio_devices_t legacyType, const char* legacyAddress) {
    AudioDevice aidl;
    const std::string stringAddress = VALUE_OR_RETURN(
    aidl.type = VALUE_OR_RETURN(
            legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyType));
    const std::string aidl_id = VALUE_OR_RETURN(
            legacy2aidl_string(legacyAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN));
            legacy2aidl_string(legacyAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN));
    aidl.address = AudioDeviceAddress::make<AudioDeviceAddress::id>(aidl_id);
    return legacy2aidl_audio_device_AudioDevice(legacyType, stringAddress);
    return aidl;
}
}


ConversionResult<AudioDevice>
ConversionResult<AudioDevice>
legacy2aidl_audio_device_AudioDevice(
legacy2aidl_audio_device_AudioDevice(
        audio_devices_t legacyType, const String8& legacyAddress) {
        audio_devices_t legacyType, const String8& legacyAddress) {
    const std::string stringAddress = VALUE_OR_RETURN(legacy2aidl_String8_string(legacyAddress));
    return legacy2aidl_audio_device_AudioDevice(legacyType, stringAddress);
}

ConversionResult<AudioDevice>
legacy2aidl_audio_device_AudioDevice(
        audio_devices_t legacyType, const std::string& legacyAddress) {
    using Tag = AudioDeviceAddress::Tag;
    AudioDevice aidl;
    AudioDevice aidl;
    aidl.type = VALUE_OR_RETURN(
    aidl.type = VALUE_OR_RETURN(
            legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyType));
            legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyType));
    const std::string aidl_id = VALUE_OR_RETURN(
    // 'legacyAddress' can be empty even when the connection type is not.
            legacy2aidl_String8_string(legacyAddress));
    // This happens for device ports that act as "blueprints". In this case
    aidl.address = AudioDeviceAddress::make<AudioDeviceAddress::id>(aidl_id);
    // we pass an empty string using the 'id' variant.
    if (!legacyAddress.empty()) {
        switch (suggestDeviceAddressTag(aidl.type)) {
            case Tag::mac: {
                std::vector<uint8_t> mac(6);
                int status = sscanf(legacyAddress.c_str(), "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
                        &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
                if (status != mac.size()) {
                    ALOGE("%s: malformed MAC address: \"%s\"", __func__, legacyAddress.c_str());
                    return unexpected(BAD_VALUE);
                }
                aidl.address = AudioDeviceAddress::make<AudioDeviceAddress::mac>(std::move(mac));
            } break;
            case Tag::ipv4: {
                std::vector<uint8_t> ipv4(4);
                int status = sscanf(legacyAddress.c_str(), "%hhu.%hhu.%hhu.%hhu",
                        &ipv4[0], &ipv4[1], &ipv4[2], &ipv4[3]);
                if (status != ipv4.size()) {
                    ALOGE("%s: malformed IPv4 address: \"%s\"", __func__, legacyAddress.c_str());
                    return unexpected(BAD_VALUE);
                }
                aidl.address = AudioDeviceAddress::make<AudioDeviceAddress::ipv4>(std::move(ipv4));
            } break;
            case Tag::ipv6: {
                std::vector<int32_t> ipv6(8);
                int status = sscanf(legacyAddress.c_str(), "%X:%X:%X:%X:%X:%X:%X:%X",
                        &ipv6[0], &ipv6[1], &ipv6[2], &ipv6[3], &ipv6[4], &ipv6[5], &ipv6[6],
                        &ipv6[7]);
                if (status != ipv6.size()) {
                    ALOGE("%s: malformed IPv6 address: \"%s\"", __func__, legacyAddress.c_str());
                    return unexpected(BAD_VALUE);
                }
                aidl.address = AudioDeviceAddress::make<AudioDeviceAddress::ipv6>(std::move(ipv6));
            } break;
            case Tag::alsa: {
                std::vector<int32_t> alsa(2);
                int status = sscanf(legacyAddress.c_str(), "card=%d;device=%d", &alsa[0], &alsa[1]);
                if (status != alsa.size()) {
                    ALOGE("%s: malformed ALSA address: \"%s\"", __func__, legacyAddress.c_str());
                    return unexpected(BAD_VALUE);
                }
                aidl.address = AudioDeviceAddress::make<AudioDeviceAddress::alsa>(std::move(alsa));
            } break;
            case Tag::id: {
                aidl.address = AudioDeviceAddress::make<AudioDeviceAddress::id>(legacyAddress);
            } break;
        }
    } else {
        aidl.address = AudioDeviceAddress::make<AudioDeviceAddress::id>(legacyAddress);
    }
    return aidl;
    return aidl;
}
}


@@ -3009,6 +3116,8 @@ legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfos(


}  // namespace android
}  // namespace android


#undef GET_DEVICE_DESC_CONNECTION

#if defined(BACKEND_NDK)
#if defined(BACKEND_NDK)
}  // aidl
}  // aidl
#endif
#endif
+5 −0
Original line number Original line Diff line number Diff line
@@ -190,6 +190,9 @@ ConversionResult<audio_devices_t> aidl2legacy_AudioDeviceDescription_audio_devic
ConversionResult<media::audio::common::AudioDeviceDescription>
ConversionResult<media::audio::common::AudioDeviceDescription>
legacy2aidl_audio_devices_t_AudioDeviceDescription(audio_devices_t legacy);
legacy2aidl_audio_devices_t_AudioDeviceDescription(audio_devices_t legacy);


media::audio::common::AudioDeviceAddress::Tag suggestDeviceAddressTag(
        const media::audio::common::AudioDeviceDescription& description);

::android::status_t aidl2legacy_AudioDevice_audio_device(
::android::status_t aidl2legacy_AudioDevice_audio_device(
        const media::audio::common::AudioDevice& aidl, audio_devices_t* legacyType,
        const media::audio::common::AudioDevice& aidl, audio_devices_t* legacyType,
        char* legacyAddress);
        char* legacyAddress);
@@ -204,6 +207,8 @@ ConversionResult<media::audio::common::AudioDevice> legacy2aidl_audio_device_Aud
        audio_devices_t legacyType, const char* legacyAddress);
        audio_devices_t legacyType, const char* legacyAddress);
ConversionResult<media::audio::common::AudioDevice> legacy2aidl_audio_device_AudioDevice(
ConversionResult<media::audio::common::AudioDevice> legacy2aidl_audio_device_AudioDevice(
        audio_devices_t legacyType, const ::android::String8& legacyAddress);
        audio_devices_t legacyType, const ::android::String8& legacyAddress);
ConversionResult<media::audio::common::AudioDevice> legacy2aidl_audio_device_AudioDevice(
        audio_devices_t legacyType, const std::string& legacyAddress);


ConversionResult<audio_extra_audio_descriptor>
ConversionResult<audio_extra_audio_descriptor>
aidl2legacy_ExtraAudioDescriptor_audio_extra_audio_descriptor(
aidl2legacy_ExtraAudioDescriptor_audio_extra_audio_descriptor(
+15 −0
Original line number Original line Diff line number Diff line
@@ -250,6 +250,12 @@ status_t AudioSystem::setMode(audio_mode_t mode) {
    return af->setMode(mode);
    return af->setMode(mode);
}
}


status_t AudioSystem::setSimulateDeviceConnections(bool enabled) {
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
    if (af == 0) return PERMISSION_DENIED;
    return af->setSimulateDeviceConnections(enabled);
}

status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) {
status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) {
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
    if (af == 0) return PERMISSION_DENIED;
    if (af == 0) return PERMISSION_DENIED;
@@ -1544,6 +1550,15 @@ status_t AudioSystem::listAudioPorts(audio_port_role_t role,
    return OK;
    return OK;
}
}


status_t AudioSystem::listDeclaredDevicePorts(media::AudioPortRole role,
                                              std::vector<media::AudioPortFw>* result) {
    if (result == nullptr) return BAD_VALUE;
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return PERMISSION_DENIED;
    RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(aps->listDeclaredDevicePorts(role, result)));
    return OK;
}

status_t AudioSystem::getAudioPort(struct audio_port_v7* port) {
status_t AudioSystem::getAudioPort(struct audio_port_v7* port) {
    if (port == nullptr) {
    if (port == nullptr) {
        return BAD_VALUE;
        return BAD_VALUE;
+8 −0
Original line number Original line Diff line number Diff line
@@ -809,6 +809,10 @@ status_t AudioFlingerClientAdapter::setDeviceConnectedState(
    return statusTFromBinderStatus(mDelegate->setDeviceConnectedState(aidlPort, connected));
    return statusTFromBinderStatus(mDelegate->setDeviceConnectedState(aidlPort, connected));
}
}


status_t AudioFlingerClientAdapter::setSimulateDeviceConnections(bool enabled) {
    return statusTFromBinderStatus(mDelegate->setSimulateDeviceConnections(enabled));
}

status_t AudioFlingerClientAdapter::setRequestedLatencyMode(
status_t AudioFlingerClientAdapter::setRequestedLatencyMode(
        audio_io_handle_t output, audio_latency_mode_t mode) {
        audio_io_handle_t output, audio_latency_mode_t mode) {
    int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
    int32_t outputAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(output));
@@ -1355,6 +1359,10 @@ Status AudioFlingerServerAdapter::setDeviceConnectedState(
    return Status::fromStatusT(mDelegate->setDeviceConnectedState(&portLegacy, connected));
    return Status::fromStatusT(mDelegate->setDeviceConnectedState(&portLegacy, connected));
}
}


Status AudioFlingerServerAdapter::setSimulateDeviceConnections(bool enabled) {
    return Status::fromStatusT(mDelegate->setSimulateDeviceConnections(enabled));
}

Status AudioFlingerServerAdapter::setRequestedLatencyMode(
Status AudioFlingerServerAdapter::setRequestedLatencyMode(
        int32_t output, media::audio::common::AudioLatencyMode modeAidl) {
        int32_t output, media::audio::common::AudioLatencyMode modeAidl) {
    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
    audio_io_handle_t outputLegacy = VALUE_OR_RETURN_BINDER(
+3 −0
Original line number Original line Diff line number Diff line
@@ -229,6 +229,9 @@ interface IAudioFlingerService {


    void setDeviceConnectedState(in AudioPortFw devicePort, boolean connected);
    void setDeviceConnectedState(in AudioPortFw devicePort, boolean connected);


    // Used for tests only. Requires AIDL HAL to work.
    void setSimulateDeviceConnections(boolean enabled);

    /**
    /**
     * Requests a given latency mode (See AudioLatencyMode.aidl) on an output stream.
     * Requests a given latency mode (See AudioLatencyMode.aidl) on an output stream.
     * This can be used when some use case on a given mixer/stream can only be enabled
     * This can be used when some use case on a given mixer/stream can only be enabled
Loading