static char * device_get_parameters(alsa_device_profile * profile, const char * keys)
{
    if (profile->card < 0 || profile->device < 0) {
        return strdup("");
    }

    struct str_parms *query = str_parms_create_str(keys);
    struct str_parms *result = str_parms_create();

    /* These keys are from hardware/libhardware/include/audio.h */
    /* supported sample rates */
    if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES)) {
        char* rates_list = profile_get_sample_rate_strs(profile);
        str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES,
                          rates_list);
        free(rates_list);
    }

    /* supported channel counts */
    if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS)) {
        char* channels_list = profile_get_channel_count_strs(profile);
        str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_CHANNELS,
                          channels_list);
        free(channels_list);
    }

    /* supported sample formats */
    if (str_parms_has_key(query, AUDIO_PARAMETER_STREAM_SUP_FORMATS)) {
        char * format_params = profile_get_format_strs(profile);
        str_parms_add_str(result, AUDIO_PARAMETER_STREAM_SUP_FORMATS,
                          format_params);
        free(format_params);
    }
    str_parms_destroy(query);

    char* result_str = str_parms_to_str(result);
    str_parms_destroy(result);

    ALOGV("device_get_parameters = %s", result_str);

    return result_str;
}
static int usb_close_output(hw_ext_module_t * hw_module,audio_devices_t   device){
    struct usb_internal_data_s * usb_info = (struct usb_internal_data_s *)hw_module->data;
    audio_policy_anm *apm=hw_module->apm;
    struct str_parms *param;

    if(usb_info==NULL)
        return -1;

    switch(usb_info->state) {
        case IO_OPENED:
        case IO_DISCONNECTED:
            //continue treatment
            break;
        case IO_CONNECTED:
            ALOG_WARN("usb_close_output : USB output is not in disconnected state ; Impossible to close it");
            return -1;
            break;
        case IO_CLOSED:
            ALOG_WARN("usb_close_output : already closed");
            return 0;
            break;
        default:
            ALOG_WARN("usb_close_output : unknown state");
    }

    if (usb_info->output_handle <=0 ) {
        ALOG_WARN("USB output is invalid ; Impossible to connect it");
        return -1;
    }
    ALOG_INFO("USB request closing ");
    param = str_parms_create_str("closing");
    str_parms_add_str(param, "closing", "true");
    apm->mp_client_interface->set_parameters(apm->mService, usb_info->output_handle, str_parms_to_str(param), 0);
    str_parms_destroy(param);

    apm->mp_client_interface->close_output(apm->mService, usb_info->output_handle);
    ALOG_INFO("Usb closed ");
    return(usb_init(hw_module));
}
char * hdmi_out_get_parameters(const struct audio_stream *stream,
			 const char *keys)
{
    struct str_parms *query = str_parms_create_str(keys);
    char *str;
    char value[256];
    struct str_parms *reply = str_parms_create();
    int status;
    hdmi_audio_caps_t caps;

    TRACEM("stream=%p keys='%s'", stream, keys);

    if (hdmi_query_audio_caps(HDMI_EDID_PATH, &caps)) {
        ALOGE("Unable to get the HDMI audio capabilities");
        str = calloc(1, 1);
        goto end;
    }

    status = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_SUP_CHANNELS,
                                value, sizeof(value));
    if (status >= 0) {
        unsigned sa = caps.speaker_alloc;
        bool first = true;

        /* STEREO is intentionally skipped.  This code is only
         * executed for the 'DIRECT' interface, and we don't
         * want stereo on a DIRECT thread.
         */
        value[0] = '\0';
        if (SUPPORTS_ARR(sa, MASK_CEA_QUAD)) {
            if (!first) {
                strcat(value, "|");
            }
            first = false;
            strcat(value, "AUDIO_CHANNEL_OUT_QUAD");
        }
        if (SUPPORTS_ARR(sa, MASK_CEA_SURROUND)) {
            if (!first) {
                strcat(value, "|");
            }
            first = false;
            strcat(value, "AUDIO_CHANNEL_OUT_SURROUND");
        }
        if (SUPPORTS_ARR(sa, MASK_CEA_5POINT1)) {
            if (!first) {
                strcat(value, "|");
            }
            first = false;
            strcat(value, "AUDIO_CHANNEL_OUT_5POINT1");
        }
        if (SUPPORTS_ARR(sa, MASK_CEA_7POINT1)) {
            if (!first) {
                strcat(value, "|");
            }
            first = false;
            strcat(value, "AUDIO_CHANNEL_OUT_7POINT1");
        }
        str_parms_add_str(reply, AUDIO_PARAMETER_STREAM_SUP_CHANNELS, value);
        str = strdup(str_parms_to_str(reply));
    } else {
        str = strdup(keys);
    }

    ALOGV("%s() reply: '%s'", __func__, str);

end:
    str_parms_destroy(query);
    str_parms_destroy(reply);
    return str;
}