Loading system/btif/src/btif_a2dp_control.cc +207 −190 Original line number Diff line number Diff line Loading @@ -62,69 +62,40 @@ void btif_a2dp_control_cleanup(void) { } } static void btif_a2dp_recv_ctrl_data(void) { tA2DP_CTRL_CMD cmd = A2DP_CTRL_CMD_NONE; int n; uint8_t read_cmd = 0; /* The read command size is one octet */ n = UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, &read_cmd, 1); cmd = static_cast<tA2DP_CTRL_CMD>(read_cmd); /* detach on ctrl channel means audioflinger process was terminated */ if (n == 0) { APPL_TRACE_WARNING("%s: CTRL CH DETACHED", __func__); UIPC_Close(*a2dp_uipc, UIPC_CH_ID_AV_CTRL); return; } // Don't log A2DP_CTRL_GET_PRESENTATION_POSITION by default, because it // could be very chatty when audio is streaming. if (cmd == A2DP_CTRL_GET_PRESENTATION_POSITION) { APPL_TRACE_DEBUG("%s: a2dp-ctrl-cmd : %s", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); } else { APPL_TRACE_WARNING("%s: a2dp-ctrl-cmd : %s", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); } a2dp_cmd_pending = cmd; switch (cmd) { case A2DP_CTRL_CMD_CHECK_READY: static tA2DP_CTRL_ACK btif_a2dp_control_on_check_ready() { if (btif_a2dp_source_media_task_is_shutting_down()) { APPL_TRACE_WARNING("%s: A2DP command %s while media task shutting down", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); return; APPL_TRACE_WARNING( "%s: A2DP command check ready while media task shutting down", __func__); return A2DP_CTRL_ACK_FAILURE; } /* check whether AV is ready to setup A2DP datapath */ if (btif_av_stream_ready() || btif_av_stream_started_ready()) { btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); return A2DP_CTRL_ACK_SUCCESS; } else { APPL_TRACE_WARNING("%s: A2DP command %s while AV stream is not ready", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); APPL_TRACE_WARNING( "%s: A2DP command check ready while AV stream is not ready", __func__); return A2DP_CTRL_ACK_FAILURE; } } break; case A2DP_CTRL_CMD_START: static tA2DP_CTRL_ACK btif_a2dp_control_on_start() { /* * Don't send START request to stack while we are in a call. * Some headsets such as "Sony MW600", don't allow AVDTP START * while in a call, and respond with BAD_STATE. */ if (!bluetooth::headset::IsCallIdle()) { APPL_TRACE_WARNING("%s: A2DP command %s while call state is busy", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); btif_a2dp_command_ack(A2DP_CTRL_ACK_INCALL_FAILURE); break; APPL_TRACE_WARNING("%s: A2DP command start while call state is busy", __func__); return A2DP_CTRL_ACK_INCALL_FAILURE; } if (btif_a2dp_source_is_streaming()) { APPL_TRACE_WARNING("%s: A2DP command %s while source is streaming", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); break; APPL_TRACE_WARNING("%s: A2DP command start while source is streaming", __func__); return A2DP_CTRL_ACK_FAILURE; } if (btif_av_stream_ready()) { Loading @@ -138,9 +109,7 @@ static void btif_a2dp_recv_ctrl_data(void) { * procedure is completed, othewise send it now. */ btif_av_stream_start(); if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); break; if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) return A2DP_CTRL_ACK_SUCCESS; } if (btif_av_stream_started_ready()) { Loading @@ -150,30 +119,28 @@ static void btif_a2dp_recv_ctrl_data(void) { */ UIPC_Open(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb, A2DP_DATA_PATH); btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); break; return A2DP_CTRL_ACK_SUCCESS; } APPL_TRACE_WARNING("%s: A2DP command start while AV stream is not ready", __func__); return A2DP_CTRL_ACK_FAILURE; } APPL_TRACE_WARNING("%s: A2DP command %s while AV stream is not ready", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); break; case A2DP_CTRL_CMD_STOP: static tA2DP_CTRL_ACK btif_a2dp_control_on_stop() { if (btif_av_get_peer_sep() == AVDT_TSEP_SNK && !btif_a2dp_source_is_streaming()) { /* We are already stopped, just ack back */ btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); break; return A2DP_CTRL_ACK_SUCCESS; } btif_av_stream_stop(RawAddress::kEmpty); btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); break; return A2DP_CTRL_ACK_SUCCESS; } case A2DP_CTRL_CMD_SUSPEND: static void btif_a2dp_control_on_suspend() { /* Local suspend */ if (btif_av_stream_started_ready()) { btif_av_stream_suspend(); break; return; } /* If we are not in started state, just ack back ok and let * audioflinger close the channel. This can happen if we are Loading @@ -181,9 +148,9 @@ static void btif_a2dp_recv_ctrl_data(void) { */ btif_av_clear_remote_suspend_flag(); btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); break; } case A2DP_CTRL_GET_INPUT_AUDIO_CONFIG: { static void btif_a2dp_control_on_get_input_audio_config() { tA2DP_SAMPLE_RATE sample_rate = btif_a2dp_sink_get_sample_rate(); tA2DP_CHANNEL_COUNT channel_count = btif_a2dp_sink_get_channel_count(); Loading @@ -193,10 +160,9 @@ static void btif_a2dp_recv_ctrl_data(void) { sizeof(tA2DP_SAMPLE_RATE)); UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, &channel_count, sizeof(tA2DP_CHANNEL_COUNT)); break; } case A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG: { static void btif_a2dp_control_on_get_output_audio_config() { btav_a2dp_codec_config_t codec_config; btav_a2dp_codec_config_t codec_capability; codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE; Loading Loading @@ -227,18 +193,15 @@ static void btif_a2dp_recv_ctrl_data(void) { UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, reinterpret_cast<const uint8_t*>(&codec_capability.sample_rate), sizeof(btav_a2dp_codec_sample_rate_t)); UIPC_Send( *a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, reinterpret_cast<const uint8_t*>(&codec_capability.bits_per_sample), sizeof(btav_a2dp_codec_bits_per_sample_t)); UIPC_Send( *a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, reinterpret_cast<const uint8_t*>(&codec_capability.channel_mode), sizeof(btav_a2dp_codec_channel_mode_t)); break; } case A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG: { static void btif_a2dp_control_on_set_output_audio_config() { btav_a2dp_codec_config_t codec_config; codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE; codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE; Loading @@ -250,9 +213,8 @@ static void btif_a2dp_recv_ctrl_data(void) { reinterpret_cast<uint8_t*>(&codec_config.sample_rate), sizeof(btav_a2dp_codec_sample_rate_t)) != sizeof(btav_a2dp_codec_sample_rate_t)) { APPL_TRACE_ERROR("%s: Error reading sample rate from audio HAL", __func__); break; APPL_TRACE_ERROR("%s: Error reading sample rate from audio HAL", __func__); return; } if (UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, reinterpret_cast<uint8_t*>(&codec_config.bits_per_sample), Loading @@ -260,15 +222,14 @@ static void btif_a2dp_recv_ctrl_data(void) { sizeof(btav_a2dp_codec_bits_per_sample_t)) { APPL_TRACE_ERROR("%s: Error reading bits per sample from audio HAL", __func__); break; return; } if (UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, reinterpret_cast<uint8_t*>(&codec_config.channel_mode), sizeof(btav_a2dp_codec_channel_mode_t)) != sizeof(btav_a2dp_codec_channel_mode_t)) { APPL_TRACE_ERROR("%s: Error reading channel mode from audio HAL", __func__); break; APPL_TRACE_ERROR("%s: Error reading channel mode from audio HAL", __func__); return; } APPL_TRACE_DEBUG( "%s: A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG: " Loading @@ -277,15 +238,13 @@ static void btif_a2dp_recv_ctrl_data(void) { __func__, codec_config.sample_rate, codec_config.bits_per_sample, codec_config.channel_mode); btif_a2dp_source_feeding_update_req(codec_config); break; } case A2DP_CTRL_GET_PRESENTATION_POSITION: { static void btif_a2dp_control_on_get_presentation_position() { btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, (uint8_t*)&(delay_report_stats.total_bytes_read), sizeof(uint64_t)); (uint8_t*)&(delay_report_stats.total_bytes_read), sizeof(uint64_t)); UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, (uint8_t*)&(delay_report_stats.audio_delay), sizeof(uint16_t)); Loading @@ -294,10 +253,68 @@ static void btif_a2dp_recv_ctrl_data(void) { sizeof(seconds)); uint32_t nsec = delay_report_stats.timestamp.tv_nsec; UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, (uint8_t*)&nsec, sizeof(nsec)); break; UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, (uint8_t*)&nsec, sizeof(nsec)); } static void btif_a2dp_recv_ctrl_data(void) { tA2DP_CTRL_CMD cmd = A2DP_CTRL_CMD_NONE; int n; uint8_t read_cmd = 0; /* The read command size is one octet */ n = UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, &read_cmd, 1); cmd = static_cast<tA2DP_CTRL_CMD>(read_cmd); /* detach on ctrl channel means audioflinger process was terminated */ if (n == 0) { APPL_TRACE_WARNING("%s: CTRL CH DETACHED", __func__); UIPC_Close(*a2dp_uipc, UIPC_CH_ID_AV_CTRL); return; } // Don't log A2DP_CTRL_GET_PRESENTATION_POSITION by default, because it // could be very chatty when audio is streaming. if (cmd == A2DP_CTRL_GET_PRESENTATION_POSITION) { APPL_TRACE_DEBUG("%s: a2dp-ctrl-cmd : %s", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); } else { APPL_TRACE_WARNING("%s: a2dp-ctrl-cmd : %s", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); } a2dp_cmd_pending = cmd; switch (cmd) { case A2DP_CTRL_CMD_CHECK_READY: btif_a2dp_command_ack(btif_a2dp_control_on_check_ready()); break; case A2DP_CTRL_CMD_START: btif_a2dp_command_ack(btif_a2dp_control_on_start()); break; case A2DP_CTRL_CMD_STOP: btif_a2dp_command_ack(btif_a2dp_control_on_stop()); break; case A2DP_CTRL_CMD_SUSPEND: btif_a2dp_control_on_suspend(); break; case A2DP_CTRL_GET_INPUT_AUDIO_CONFIG: btif_a2dp_control_on_get_input_audio_config(); break; case A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG: btif_a2dp_control_on_get_output_audio_config(); break; case A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG: btif_a2dp_control_on_set_output_audio_config(); break; case A2DP_CTRL_GET_PRESENTATION_POSITION: btif_a2dp_control_on_get_presentation_position(); break; default: APPL_TRACE_ERROR("%s: UNSUPPORTED CMD (%d)", __func__, cmd); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); Loading Loading
system/btif/src/btif_a2dp_control.cc +207 −190 Original line number Diff line number Diff line Loading @@ -62,69 +62,40 @@ void btif_a2dp_control_cleanup(void) { } } static void btif_a2dp_recv_ctrl_data(void) { tA2DP_CTRL_CMD cmd = A2DP_CTRL_CMD_NONE; int n; uint8_t read_cmd = 0; /* The read command size is one octet */ n = UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, &read_cmd, 1); cmd = static_cast<tA2DP_CTRL_CMD>(read_cmd); /* detach on ctrl channel means audioflinger process was terminated */ if (n == 0) { APPL_TRACE_WARNING("%s: CTRL CH DETACHED", __func__); UIPC_Close(*a2dp_uipc, UIPC_CH_ID_AV_CTRL); return; } // Don't log A2DP_CTRL_GET_PRESENTATION_POSITION by default, because it // could be very chatty when audio is streaming. if (cmd == A2DP_CTRL_GET_PRESENTATION_POSITION) { APPL_TRACE_DEBUG("%s: a2dp-ctrl-cmd : %s", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); } else { APPL_TRACE_WARNING("%s: a2dp-ctrl-cmd : %s", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); } a2dp_cmd_pending = cmd; switch (cmd) { case A2DP_CTRL_CMD_CHECK_READY: static tA2DP_CTRL_ACK btif_a2dp_control_on_check_ready() { if (btif_a2dp_source_media_task_is_shutting_down()) { APPL_TRACE_WARNING("%s: A2DP command %s while media task shutting down", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); return; APPL_TRACE_WARNING( "%s: A2DP command check ready while media task shutting down", __func__); return A2DP_CTRL_ACK_FAILURE; } /* check whether AV is ready to setup A2DP datapath */ if (btif_av_stream_ready() || btif_av_stream_started_ready()) { btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); return A2DP_CTRL_ACK_SUCCESS; } else { APPL_TRACE_WARNING("%s: A2DP command %s while AV stream is not ready", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); APPL_TRACE_WARNING( "%s: A2DP command check ready while AV stream is not ready", __func__); return A2DP_CTRL_ACK_FAILURE; } } break; case A2DP_CTRL_CMD_START: static tA2DP_CTRL_ACK btif_a2dp_control_on_start() { /* * Don't send START request to stack while we are in a call. * Some headsets such as "Sony MW600", don't allow AVDTP START * while in a call, and respond with BAD_STATE. */ if (!bluetooth::headset::IsCallIdle()) { APPL_TRACE_WARNING("%s: A2DP command %s while call state is busy", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); btif_a2dp_command_ack(A2DP_CTRL_ACK_INCALL_FAILURE); break; APPL_TRACE_WARNING("%s: A2DP command start while call state is busy", __func__); return A2DP_CTRL_ACK_INCALL_FAILURE; } if (btif_a2dp_source_is_streaming()) { APPL_TRACE_WARNING("%s: A2DP command %s while source is streaming", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); break; APPL_TRACE_WARNING("%s: A2DP command start while source is streaming", __func__); return A2DP_CTRL_ACK_FAILURE; } if (btif_av_stream_ready()) { Loading @@ -138,9 +109,7 @@ static void btif_a2dp_recv_ctrl_data(void) { * procedure is completed, othewise send it now. */ btif_av_stream_start(); if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); break; if (btif_av_get_peer_sep() == AVDT_TSEP_SRC) return A2DP_CTRL_ACK_SUCCESS; } if (btif_av_stream_started_ready()) { Loading @@ -150,30 +119,28 @@ static void btif_a2dp_recv_ctrl_data(void) { */ UIPC_Open(*a2dp_uipc, UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb, A2DP_DATA_PATH); btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); break; return A2DP_CTRL_ACK_SUCCESS; } APPL_TRACE_WARNING("%s: A2DP command start while AV stream is not ready", __func__); return A2DP_CTRL_ACK_FAILURE; } APPL_TRACE_WARNING("%s: A2DP command %s while AV stream is not ready", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); break; case A2DP_CTRL_CMD_STOP: static tA2DP_CTRL_ACK btif_a2dp_control_on_stop() { if (btif_av_get_peer_sep() == AVDT_TSEP_SNK && !btif_a2dp_source_is_streaming()) { /* We are already stopped, just ack back */ btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); break; return A2DP_CTRL_ACK_SUCCESS; } btif_av_stream_stop(RawAddress::kEmpty); btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); break; return A2DP_CTRL_ACK_SUCCESS; } case A2DP_CTRL_CMD_SUSPEND: static void btif_a2dp_control_on_suspend() { /* Local suspend */ if (btif_av_stream_started_ready()) { btif_av_stream_suspend(); break; return; } /* If we are not in started state, just ack back ok and let * audioflinger close the channel. This can happen if we are Loading @@ -181,9 +148,9 @@ static void btif_a2dp_recv_ctrl_data(void) { */ btif_av_clear_remote_suspend_flag(); btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); break; } case A2DP_CTRL_GET_INPUT_AUDIO_CONFIG: { static void btif_a2dp_control_on_get_input_audio_config() { tA2DP_SAMPLE_RATE sample_rate = btif_a2dp_sink_get_sample_rate(); tA2DP_CHANNEL_COUNT channel_count = btif_a2dp_sink_get_channel_count(); Loading @@ -193,10 +160,9 @@ static void btif_a2dp_recv_ctrl_data(void) { sizeof(tA2DP_SAMPLE_RATE)); UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, &channel_count, sizeof(tA2DP_CHANNEL_COUNT)); break; } case A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG: { static void btif_a2dp_control_on_get_output_audio_config() { btav_a2dp_codec_config_t codec_config; btav_a2dp_codec_config_t codec_capability; codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE; Loading Loading @@ -227,18 +193,15 @@ static void btif_a2dp_recv_ctrl_data(void) { UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, reinterpret_cast<const uint8_t*>(&codec_capability.sample_rate), sizeof(btav_a2dp_codec_sample_rate_t)); UIPC_Send( *a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, reinterpret_cast<const uint8_t*>(&codec_capability.bits_per_sample), sizeof(btav_a2dp_codec_bits_per_sample_t)); UIPC_Send( *a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, reinterpret_cast<const uint8_t*>(&codec_capability.channel_mode), sizeof(btav_a2dp_codec_channel_mode_t)); break; } case A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG: { static void btif_a2dp_control_on_set_output_audio_config() { btav_a2dp_codec_config_t codec_config; codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE; codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE; Loading @@ -250,9 +213,8 @@ static void btif_a2dp_recv_ctrl_data(void) { reinterpret_cast<uint8_t*>(&codec_config.sample_rate), sizeof(btav_a2dp_codec_sample_rate_t)) != sizeof(btav_a2dp_codec_sample_rate_t)) { APPL_TRACE_ERROR("%s: Error reading sample rate from audio HAL", __func__); break; APPL_TRACE_ERROR("%s: Error reading sample rate from audio HAL", __func__); return; } if (UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, reinterpret_cast<uint8_t*>(&codec_config.bits_per_sample), Loading @@ -260,15 +222,14 @@ static void btif_a2dp_recv_ctrl_data(void) { sizeof(btav_a2dp_codec_bits_per_sample_t)) { APPL_TRACE_ERROR("%s: Error reading bits per sample from audio HAL", __func__); break; return; } if (UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, reinterpret_cast<uint8_t*>(&codec_config.channel_mode), sizeof(btav_a2dp_codec_channel_mode_t)) != sizeof(btav_a2dp_codec_channel_mode_t)) { APPL_TRACE_ERROR("%s: Error reading channel mode from audio HAL", __func__); break; APPL_TRACE_ERROR("%s: Error reading channel mode from audio HAL", __func__); return; } APPL_TRACE_DEBUG( "%s: A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG: " Loading @@ -277,15 +238,13 @@ static void btif_a2dp_recv_ctrl_data(void) { __func__, codec_config.sample_rate, codec_config.bits_per_sample, codec_config.channel_mode); btif_a2dp_source_feeding_update_req(codec_config); break; } case A2DP_CTRL_GET_PRESENTATION_POSITION: { static void btif_a2dp_control_on_get_presentation_position() { btif_a2dp_command_ack(A2DP_CTRL_ACK_SUCCESS); UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, (uint8_t*)&(delay_report_stats.total_bytes_read), sizeof(uint64_t)); (uint8_t*)&(delay_report_stats.total_bytes_read), sizeof(uint64_t)); UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, (uint8_t*)&(delay_report_stats.audio_delay), sizeof(uint16_t)); Loading @@ -294,10 +253,68 @@ static void btif_a2dp_recv_ctrl_data(void) { sizeof(seconds)); uint32_t nsec = delay_report_stats.timestamp.tv_nsec; UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, (uint8_t*)&nsec, sizeof(nsec)); break; UIPC_Send(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, 0, (uint8_t*)&nsec, sizeof(nsec)); } static void btif_a2dp_recv_ctrl_data(void) { tA2DP_CTRL_CMD cmd = A2DP_CTRL_CMD_NONE; int n; uint8_t read_cmd = 0; /* The read command size is one octet */ n = UIPC_Read(*a2dp_uipc, UIPC_CH_ID_AV_CTRL, &read_cmd, 1); cmd = static_cast<tA2DP_CTRL_CMD>(read_cmd); /* detach on ctrl channel means audioflinger process was terminated */ if (n == 0) { APPL_TRACE_WARNING("%s: CTRL CH DETACHED", __func__); UIPC_Close(*a2dp_uipc, UIPC_CH_ID_AV_CTRL); return; } // Don't log A2DP_CTRL_GET_PRESENTATION_POSITION by default, because it // could be very chatty when audio is streaming. if (cmd == A2DP_CTRL_GET_PRESENTATION_POSITION) { APPL_TRACE_DEBUG("%s: a2dp-ctrl-cmd : %s", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); } else { APPL_TRACE_WARNING("%s: a2dp-ctrl-cmd : %s", __func__, audio_a2dp_hw_dump_ctrl_event(cmd)); } a2dp_cmd_pending = cmd; switch (cmd) { case A2DP_CTRL_CMD_CHECK_READY: btif_a2dp_command_ack(btif_a2dp_control_on_check_ready()); break; case A2DP_CTRL_CMD_START: btif_a2dp_command_ack(btif_a2dp_control_on_start()); break; case A2DP_CTRL_CMD_STOP: btif_a2dp_command_ack(btif_a2dp_control_on_stop()); break; case A2DP_CTRL_CMD_SUSPEND: btif_a2dp_control_on_suspend(); break; case A2DP_CTRL_GET_INPUT_AUDIO_CONFIG: btif_a2dp_control_on_get_input_audio_config(); break; case A2DP_CTRL_GET_OUTPUT_AUDIO_CONFIG: btif_a2dp_control_on_get_output_audio_config(); break; case A2DP_CTRL_SET_OUTPUT_AUDIO_CONFIG: btif_a2dp_control_on_set_output_audio_config(); break; case A2DP_CTRL_GET_PRESENTATION_POSITION: btif_a2dp_control_on_get_presentation_position(); break; default: APPL_TRACE_ERROR("%s: UNSUPPORTED CMD (%d)", __func__, cmd); btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); Loading