Android源码--listAudioPorts调用过程

来源:互联网 发布:西班牙菜 知乎 编辑:程序博客网 时间:2024/05/18 13:12
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();
}
0 0