Android源码--listAudioPorts调用过程

本文详细介绍了Android系统中AudioService如何通过JNI调用AudioSystem的listAudioPorts方法来获取音频端口信息的过程。该过程涉及AudioPolicyService、IAudioPolicyService接口、AudioPolicyManager等多个组件,最终在AudioPolicyManager.cpp中实现设备接口的查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AudioService.java
private void configureHdmiPlugIntent(Intent intent, int state) {
    ArrayList<AudioPort> ports = new ArrayList<AudioPort>();
    int[] portGeneration = new int[1];
    int status = AudioSystem.listAudioPorts(ports, portGeneration);
}

AudioService.java
// declare native method
public static native int listAudioPorts(ArrayList<AudioPort> ports, int[] generation);

android_media_AudioSystem.cpp
// JNI call
static jint android_media_AudioSystem_listAudioPorts(JNIEnv *env, jobject clazz, jobject jPorts, jintArray jGeneration) {
    unsigned int numPorts;
    struct audio_port *nPorts = NULL;
    do {
        numPorts = 0;
        // get numPorts generation1
        AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_NONE, &numPorts, NULL, &generation1);
        nPorts = (struct audio_port *)realloc(nPorts, numPorts * sizeof(struct audio_port));
        // get numPorts nPorts generation
        AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_NONE, &numPorts, nPorts, &generation);
    } while(generation1 != generation);
    for (size_t i = 0; i < numPorts; i++) {
        jobject jAudioPort;
        // nPorts --> jAudioPort --> jPorts
        convertAudioPortFromNative(env, &jAudioPort, &nPorts[i]);
        env->CallBooleanMethod(jPorts, gArrayListMethods.add, jAudioPort);
    }
}

AudioSystem.cpp
status_t AudioSystem::listAudioPorts(audio_port_role_t role,
    audio_port_type_t type, unsigned int *num_ports,
    struct audio_port *ports, unsigned int *generation) {
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    return aps->listAudioPorts(role, type, num_ports, ports, generation);
}

IAudioPolicyService.h
/* List available audio ports and their attributes */
virtual status_t listAudioPorts(audio_port_role_t role,
    audio_port_type_t type, unsigned int *num_ports,
    struct audio_port *ports, unsigned int *generation) = 0;

IAudioPolicyService.cpp
virtual status_t listAudioPorts(audio_port_role_t role,
    audio_port_type_t type, unsigned int *num_ports,
    struct audio_port *ports, unsigned int *generation) {
    // Communicate with binder
    Parcel data, reply;
    data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
    unsigned int numPortsReq = (ports == NULL) ? 0 : *num_ports;
    data.writeInt32(role);
    data.writeInt32(type);
    data.writeInt32(numPortsReq);
    remote()->transact(LIST_AUDIO_PORTS, data, &reply);
    status = (status_t)reply.readInt32();
    *num_ports = (unsigned int)reply.readInt32();
    if (numPortsReq > *num_ports) { numPortsReq = *num_ports; }
    reply.read(ports, numPortsReq * sizeof(struct audio_port));
    *generation = reply.readInt32();
}

AudioPolicyService.h
virtual status_t listAudioPorts(audio_port_role_t role,
    audio_port_type_t type, unsigned int *num_ports,
    struct audio_port *ports, unsigned int *generation);

AudioPolicyInterface.h
virtual status_t listAudioPorts(audio_port_role_t role,
    audio_port_type_t type, unsigned int *num_ports,
    struct audio_port *ports, unsigned int *generation) = 0;

AudioPolicyInterfaceImpl.cpp
status_t AudioPolicyService::listAudioPorts(audio_port_role_t role,
    audio_port_type_t type, unsigned int *num_ports,
    struct audio_port *ports, unsigned int *generation) {
    return mAudioPolicyManager->listAudioPorts(role, type, num_ports, ports, generation);
}

AudioPolicyManager.h
class AudioPolicyManager : public AudioPolicyInterface, public AudioPolicyManagerObserver
virtual status_t listAudioPorts(audio_port_role_t role,
    audio_port_type_t type, unsigned int *num_ports,
    struct audio_port *ports, unsigned int *generation);

// 最终实现在AudioPolicyManager.cpp中,查询设备的接口。
AudioPolicyManager.cpp
status_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
    audio_port_type_t type, unsigned int *num_ports,
    struct audio_port *ports, unsigned int *generation) {
    if (ports == NULL) { *num_ports = 0; }
    size_t portsWritten = 0;
    size_t portsMax = *num_ports;
    *num_ports = 0;
    for (size_t i = 0; i < mAvailableOutputDevices.size(); i++)
    (*num_ports)++;
    for (size_t i = 0; i < mAvailableInputDevices.size(); i++)
    (*num_ports)++;
    for (size_t i = 0; i < mInputs.size() && portsWritten < portsMax; i++)
        *num_ports += mInputs.size();
    for (size_t i = 0; i < mOutputs.size(); i++) {
    numOutputs++;
        *num_ports += numOutputs;
    }
    *generation = curAudioPortGeneration();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值