Loading system/btif/include/btif_a2dp_sink.h +15 −4 Original line number Diff line number Diff line Loading @@ -38,16 +38,27 @@ typedef enum { BTIF_A2DP_SINK_FOCUS_GRANTED = 1 } btif_a2dp_sink_focus_state_t; // Initialize and startup the A2DP Sink module. // Initialize the A2DP Sink module. // This function should be called by the BTIF state machine prior to using the // module. bool btif_a2dp_sink_init(void); // Startup the A2DP Sink module. // This function should be called by the BTIF state machine after // btif_a2dp_sink_init() to prepare for receiving and processing audio // streaming. bool btif_a2dp_sink_startup(void); // Shutdown and cleanup the A2DP Sink module. // This function should be called by the BTIF state machine during // graceful shutdown and cleanup. // Shutdown the A2DP Sink module. // This function should be called by the BTIF state machine before // btif_a2dp_sink_cleanup() to shutdown the processing of the audio streaming. void btif_a2dp_sink_shutdown(void); // Cleanup the A2DP Sink module. // This function should be called by the BTIF state machine during graceful // cleanup. void btif_a2dp_sink_cleanup(void); // Get the audio sample rate for the A2DP Sink module. tA2DP_SAMPLE_RATE btif_a2dp_sink_get_sample_rate(void); Loading system/btif/include/btif_a2dp_source.h +13 −4 Original line number Diff line number Diff line Loading @@ -24,16 +24,25 @@ #include "bta_av_api.h" // Initialize and startup the A2DP Source module. // Initialize the A2DP Source module. // This function should be called by the BTIF state machine prior to using the // module. bool btif_a2dp_source_init(void); // Startup the A2DP Source module. // This function should be called by the BTIF state machine after // btif_a2dp_source_init() to prepare to start streaming. bool btif_a2dp_source_startup(void); // Shutdown and cleanup the A2DP Source module. // This function should be called by the BTIF state machine during // graceful shutdown and cleanup. // Shutdown the A2DP Source module. // This function should be called by the BTIF state machine to stop streaming. void btif_a2dp_source_shutdown(void); // Cleanup the A2DP Source module. // This function should be called by the BTIF state machine during graceful // cleanup. void btif_a2dp_source_cleanup(void); // Check whether the A2DP Source media task is running. // Returns true if the A2DP Source media task is running, otherwise false. bool btif_a2dp_source_media_task_is_running(void); Loading system/btif/src/btif_a2dp_sink.cc +34 −6 Original line number Diff line number Diff line Loading @@ -93,8 +93,10 @@ static tBTIF_A2DP_SINK_CB btif_a2dp_sink_cb; static std::atomic<int> btif_a2dp_sink_state{BTIF_A2DP_SINK_STATE_OFF}; static void btif_a2dp_sink_init_delayed(void* context); static void btif_a2dp_sink_startup_delayed(void* context); static void btif_a2dp_sink_shutdown_delayed(void* context); static void btif_a2dp_sink_cleanup_delayed(void* context); static void btif_a2dp_sink_command_ready(fixed_queue_t* queue, void* context); static void btif_a2dp_sink_audio_handle_stop_decoding(void); static void btif_decode_alarm_cb(void* context); Loading Loading @@ -123,7 +125,7 @@ UNUSED_ATTR static const char* dump_media_event(uint16_t event) { return "UNKNOWN A2DP SINK EVENT"; } bool btif_a2dp_sink_startup(void) { bool btif_a2dp_sink_init(void) { LockGuard lock(g_mutex); if (btif_a2dp_sink_state != BTIF_A2DP_SINK_STATE_OFF) { Loading Loading @@ -156,22 +158,48 @@ bool btif_a2dp_sink_startup(void) { APPL_TRACE_EVENT("## A2DP SINK MEDIA THREAD STARTED ##"); /* Schedule the rest of the startup operations */ thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_startup_delayed, /* Schedule the rest of the operations */ thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_init_delayed, NULL); return true; } static void btif_a2dp_sink_startup_delayed(UNUSED_ATTR void* context) { static void btif_a2dp_sink_init_delayed(UNUSED_ATTR void* context) { raise_priority_a2dp(TASK_HIGH_MEDIA); btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_RUNNING; } bool btif_a2dp_sink_startup(void) { LockGuard lock(g_mutex); thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_startup_delayed, NULL); return true; } static void btif_a2dp_sink_startup_delayed(UNUSED_ATTR void* context) { LockGuard lock(g_mutex); // Nothing to do } void btif_a2dp_sink_shutdown(void) { LockGuard lock(g_mutex); thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_shutdown_delayed, NULL); } static void btif_a2dp_sink_shutdown_delayed(UNUSED_ATTR void* context) { // Nothing to do } void btif_a2dp_sink_cleanup(void) { alarm_t* decode_alarm; fixed_queue_t* cmd_msg_queue; thread_t* worker_thread; // Make sure the sink is shutdown btif_a2dp_sink_shutdown(); { LockGuard lock(g_mutex); if ((btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) || Loading @@ -198,11 +226,11 @@ void btif_a2dp_sink_shutdown(void) { // Exit the thread fixed_queue_free(cmd_msg_queue, NULL); thread_post(worker_thread, btif_a2dp_sink_shutdown_delayed, NULL); thread_post(worker_thread, btif_a2dp_sink_cleanup_delayed, NULL); thread_free(worker_thread); } static void btif_a2dp_sink_shutdown_delayed(UNUSED_ATTR void* context) { static void btif_a2dp_sink_cleanup_delayed(UNUSED_ATTR void* context) { LockGuard lock(g_mutex); fixed_queue_free(btif_a2dp_sink_cb.rx_audio_queue, NULL); btif_a2dp_sink_cb.rx_audio_queue = NULL; Loading system/btif/src/btif_a2dp_source.cc +36 −10 Original line number Diff line number Diff line Loading @@ -296,8 +296,10 @@ class BtifA2dpSource { static BtWorkerThread btif_a2dp_source_thread("btif_a2dp_source_thread"); static BtifA2dpSource btif_a2dp_source_cb; static void btif_a2dp_source_init_delayed(void); static void btif_a2dp_source_startup_delayed(void); static void btif_a2dp_source_shutdown_delayed(void); static void btif_a2dp_source_cleanup_delayed(void); static void btif_a2dp_source_audio_tx_start_event(void); static void btif_a2dp_source_audio_tx_stop_event(void); static void btif_a2dp_source_audio_tx_flush_event(void); Loading Loading @@ -372,6 +374,21 @@ void btif_a2dp_source_accumulate_stats(BtifMediaStats* src, src->Reset(); } bool btif_a2dp_source_init(void) { // Start A2DP Source media task APPL_TRACE_EVENT("## A2DP SOURCE START MEDIA THREAD ##"); btif_a2dp_source_thread.StartUp(); APPL_TRACE_EVENT("## A2DP SOURCE MEDIA THREAD STARTED ##"); btif_a2dp_source_thread.DoInThread( FROM_HERE, base::Bind(&btif_a2dp_source_init_delayed)); return true; } static void btif_a2dp_source_init_delayed(void) { // Nothing to do } bool btif_a2dp_source_startup(void) { if (btif_a2dp_source_cb.State() != BtifA2dpSource::kStateOff) { APPL_TRACE_ERROR("%s: A2DP Source media task already running", __func__); Loading @@ -382,13 +399,6 @@ bool btif_a2dp_source_startup(void) { btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateStartingUp); btif_a2dp_source_cb.tx_audio_queue = fixed_queue_new(SIZE_MAX); APPL_TRACE_EVENT("## A2DP SOURCE START MEDIA THREAD ##"); /* Start A2DP Source media task */ btif_a2dp_source_thread.StartUp(); APPL_TRACE_EVENT("## A2DP SOURCE MEDIA THREAD STARTED ##"); /* Schedule the rest of the startup operations */ btif_a2dp_source_thread.DoInThread( FROM_HERE, base::Bind(&btif_a2dp_source_startup_delayed)); Loading @@ -413,12 +423,12 @@ void btif_a2dp_source_shutdown(void) { /* Make sure no channels are restarted while shutting down */ btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateShuttingDown); APPL_TRACE_EVENT("## A2DP SOURCE STOP MEDIA THREAD ##"); // Stop the timer alarm_free(btif_a2dp_source_cb.media_alarm); btif_a2dp_source_cb.media_alarm = nullptr; // Exit the thread btif_a2dp_source_thread.DoInThread( FROM_HERE, base::Bind(&btif_a2dp_source_shutdown_delayed)); btif_a2dp_source_thread.ShutDown(); } static void btif_a2dp_source_shutdown_delayed(void) { Loading @@ -435,6 +445,22 @@ static void btif_a2dp_source_shutdown_delayed(void) { system_bt_osi::DISCONNECT_REASON_UNKNOWN, 0); } void btif_a2dp_source_cleanup(void) { // Make sure the source is shutdown btif_a2dp_source_shutdown(); btif_a2dp_source_thread.DoInThread( FROM_HERE, base::Bind(&btif_a2dp_source_cleanup_delayed)); // Exit the thread APPL_TRACE_EVENT("## A2DP SOURCE STOP MEDIA THREAD ##"); btif_a2dp_source_thread.ShutDown(); } static void btif_a2dp_source_cleanup_delayed(void) { // Nothing to do } bool btif_a2dp_source_media_task_is_running(void) { return (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateRunning); } Loading system/btif/src/btif_av.cc +6 −6 Original line number Diff line number Diff line Loading @@ -822,8 +822,8 @@ bt_status_t BtifAvSource::Init( codec_priorities_ = codec_priorities; bta_av_co_init(codec_priorities_); if (!btif_a2dp_source_startup()) { return BT_STATUS_FAIL; // Already running if (!btif_a2dp_source_init()) { return BT_STATUS_FAIL; } btif_enable_service(BTA_A2DP_SOURCE_SERVICE_ID); enabled_ = true; Loading @@ -834,7 +834,7 @@ void BtifAvSource::Cleanup() { if (!enabled_) return; btif_queue_cleanup(UUID_SERVCLASS_AUDIO_SOURCE); do_in_jni_thread(FROM_HERE, base::Bind(&btif_a2dp_source_shutdown)); do_in_jni_thread(FROM_HERE, base::Bind(&btif_a2dp_source_cleanup)); btif_disable_service(BTA_A2DP_SOURCE_SERVICE_ID); CleanupAllPeers(); Loading Loading @@ -993,8 +993,8 @@ bt_status_t BtifAvSink::Init(btav_sink_callbacks_t* callbacks) { kDefaultMaxConnectedAudioDevices); callbacks_ = callbacks; if (!btif_a2dp_sink_startup()) { return BT_STATUS_FAIL; // Already running if (!btif_a2dp_sink_init()) { return BT_STATUS_FAIL; } btif_enable_service(BTA_A2DP_SINK_SERVICE_ID); enabled_ = true; Loading @@ -1005,7 +1005,7 @@ void BtifAvSink::Cleanup() { if (!enabled_) return; btif_queue_cleanup(UUID_SERVCLASS_AUDIO_SINK); do_in_jni_thread(FROM_HERE, base::Bind(&btif_a2dp_sink_shutdown)); do_in_jni_thread(FROM_HERE, base::Bind(&btif_a2dp_sink_cleanup)); btif_disable_service(BTA_A2DP_SINK_SERVICE_ID); CleanupAllPeers(); Loading Loading
system/btif/include/btif_a2dp_sink.h +15 −4 Original line number Diff line number Diff line Loading @@ -38,16 +38,27 @@ typedef enum { BTIF_A2DP_SINK_FOCUS_GRANTED = 1 } btif_a2dp_sink_focus_state_t; // Initialize and startup the A2DP Sink module. // Initialize the A2DP Sink module. // This function should be called by the BTIF state machine prior to using the // module. bool btif_a2dp_sink_init(void); // Startup the A2DP Sink module. // This function should be called by the BTIF state machine after // btif_a2dp_sink_init() to prepare for receiving and processing audio // streaming. bool btif_a2dp_sink_startup(void); // Shutdown and cleanup the A2DP Sink module. // This function should be called by the BTIF state machine during // graceful shutdown and cleanup. // Shutdown the A2DP Sink module. // This function should be called by the BTIF state machine before // btif_a2dp_sink_cleanup() to shutdown the processing of the audio streaming. void btif_a2dp_sink_shutdown(void); // Cleanup the A2DP Sink module. // This function should be called by the BTIF state machine during graceful // cleanup. void btif_a2dp_sink_cleanup(void); // Get the audio sample rate for the A2DP Sink module. tA2DP_SAMPLE_RATE btif_a2dp_sink_get_sample_rate(void); Loading
system/btif/include/btif_a2dp_source.h +13 −4 Original line number Diff line number Diff line Loading @@ -24,16 +24,25 @@ #include "bta_av_api.h" // Initialize and startup the A2DP Source module. // Initialize the A2DP Source module. // This function should be called by the BTIF state machine prior to using the // module. bool btif_a2dp_source_init(void); // Startup the A2DP Source module. // This function should be called by the BTIF state machine after // btif_a2dp_source_init() to prepare to start streaming. bool btif_a2dp_source_startup(void); // Shutdown and cleanup the A2DP Source module. // This function should be called by the BTIF state machine during // graceful shutdown and cleanup. // Shutdown the A2DP Source module. // This function should be called by the BTIF state machine to stop streaming. void btif_a2dp_source_shutdown(void); // Cleanup the A2DP Source module. // This function should be called by the BTIF state machine during graceful // cleanup. void btif_a2dp_source_cleanup(void); // Check whether the A2DP Source media task is running. // Returns true if the A2DP Source media task is running, otherwise false. bool btif_a2dp_source_media_task_is_running(void); Loading
system/btif/src/btif_a2dp_sink.cc +34 −6 Original line number Diff line number Diff line Loading @@ -93,8 +93,10 @@ static tBTIF_A2DP_SINK_CB btif_a2dp_sink_cb; static std::atomic<int> btif_a2dp_sink_state{BTIF_A2DP_SINK_STATE_OFF}; static void btif_a2dp_sink_init_delayed(void* context); static void btif_a2dp_sink_startup_delayed(void* context); static void btif_a2dp_sink_shutdown_delayed(void* context); static void btif_a2dp_sink_cleanup_delayed(void* context); static void btif_a2dp_sink_command_ready(fixed_queue_t* queue, void* context); static void btif_a2dp_sink_audio_handle_stop_decoding(void); static void btif_decode_alarm_cb(void* context); Loading Loading @@ -123,7 +125,7 @@ UNUSED_ATTR static const char* dump_media_event(uint16_t event) { return "UNKNOWN A2DP SINK EVENT"; } bool btif_a2dp_sink_startup(void) { bool btif_a2dp_sink_init(void) { LockGuard lock(g_mutex); if (btif_a2dp_sink_state != BTIF_A2DP_SINK_STATE_OFF) { Loading Loading @@ -156,22 +158,48 @@ bool btif_a2dp_sink_startup(void) { APPL_TRACE_EVENT("## A2DP SINK MEDIA THREAD STARTED ##"); /* Schedule the rest of the startup operations */ thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_startup_delayed, /* Schedule the rest of the operations */ thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_init_delayed, NULL); return true; } static void btif_a2dp_sink_startup_delayed(UNUSED_ATTR void* context) { static void btif_a2dp_sink_init_delayed(UNUSED_ATTR void* context) { raise_priority_a2dp(TASK_HIGH_MEDIA); btif_a2dp_sink_state = BTIF_A2DP_SINK_STATE_RUNNING; } bool btif_a2dp_sink_startup(void) { LockGuard lock(g_mutex); thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_startup_delayed, NULL); return true; } static void btif_a2dp_sink_startup_delayed(UNUSED_ATTR void* context) { LockGuard lock(g_mutex); // Nothing to do } void btif_a2dp_sink_shutdown(void) { LockGuard lock(g_mutex); thread_post(btif_a2dp_sink_cb.worker_thread, btif_a2dp_sink_shutdown_delayed, NULL); } static void btif_a2dp_sink_shutdown_delayed(UNUSED_ATTR void* context) { // Nothing to do } void btif_a2dp_sink_cleanup(void) { alarm_t* decode_alarm; fixed_queue_t* cmd_msg_queue; thread_t* worker_thread; // Make sure the sink is shutdown btif_a2dp_sink_shutdown(); { LockGuard lock(g_mutex); if ((btif_a2dp_sink_state == BTIF_A2DP_SINK_STATE_OFF) || Loading @@ -198,11 +226,11 @@ void btif_a2dp_sink_shutdown(void) { // Exit the thread fixed_queue_free(cmd_msg_queue, NULL); thread_post(worker_thread, btif_a2dp_sink_shutdown_delayed, NULL); thread_post(worker_thread, btif_a2dp_sink_cleanup_delayed, NULL); thread_free(worker_thread); } static void btif_a2dp_sink_shutdown_delayed(UNUSED_ATTR void* context) { static void btif_a2dp_sink_cleanup_delayed(UNUSED_ATTR void* context) { LockGuard lock(g_mutex); fixed_queue_free(btif_a2dp_sink_cb.rx_audio_queue, NULL); btif_a2dp_sink_cb.rx_audio_queue = NULL; Loading
system/btif/src/btif_a2dp_source.cc +36 −10 Original line number Diff line number Diff line Loading @@ -296,8 +296,10 @@ class BtifA2dpSource { static BtWorkerThread btif_a2dp_source_thread("btif_a2dp_source_thread"); static BtifA2dpSource btif_a2dp_source_cb; static void btif_a2dp_source_init_delayed(void); static void btif_a2dp_source_startup_delayed(void); static void btif_a2dp_source_shutdown_delayed(void); static void btif_a2dp_source_cleanup_delayed(void); static void btif_a2dp_source_audio_tx_start_event(void); static void btif_a2dp_source_audio_tx_stop_event(void); static void btif_a2dp_source_audio_tx_flush_event(void); Loading Loading @@ -372,6 +374,21 @@ void btif_a2dp_source_accumulate_stats(BtifMediaStats* src, src->Reset(); } bool btif_a2dp_source_init(void) { // Start A2DP Source media task APPL_TRACE_EVENT("## A2DP SOURCE START MEDIA THREAD ##"); btif_a2dp_source_thread.StartUp(); APPL_TRACE_EVENT("## A2DP SOURCE MEDIA THREAD STARTED ##"); btif_a2dp_source_thread.DoInThread( FROM_HERE, base::Bind(&btif_a2dp_source_init_delayed)); return true; } static void btif_a2dp_source_init_delayed(void) { // Nothing to do } bool btif_a2dp_source_startup(void) { if (btif_a2dp_source_cb.State() != BtifA2dpSource::kStateOff) { APPL_TRACE_ERROR("%s: A2DP Source media task already running", __func__); Loading @@ -382,13 +399,6 @@ bool btif_a2dp_source_startup(void) { btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateStartingUp); btif_a2dp_source_cb.tx_audio_queue = fixed_queue_new(SIZE_MAX); APPL_TRACE_EVENT("## A2DP SOURCE START MEDIA THREAD ##"); /* Start A2DP Source media task */ btif_a2dp_source_thread.StartUp(); APPL_TRACE_EVENT("## A2DP SOURCE MEDIA THREAD STARTED ##"); /* Schedule the rest of the startup operations */ btif_a2dp_source_thread.DoInThread( FROM_HERE, base::Bind(&btif_a2dp_source_startup_delayed)); Loading @@ -413,12 +423,12 @@ void btif_a2dp_source_shutdown(void) { /* Make sure no channels are restarted while shutting down */ btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateShuttingDown); APPL_TRACE_EVENT("## A2DP SOURCE STOP MEDIA THREAD ##"); // Stop the timer alarm_free(btif_a2dp_source_cb.media_alarm); btif_a2dp_source_cb.media_alarm = nullptr; // Exit the thread btif_a2dp_source_thread.DoInThread( FROM_HERE, base::Bind(&btif_a2dp_source_shutdown_delayed)); btif_a2dp_source_thread.ShutDown(); } static void btif_a2dp_source_shutdown_delayed(void) { Loading @@ -435,6 +445,22 @@ static void btif_a2dp_source_shutdown_delayed(void) { system_bt_osi::DISCONNECT_REASON_UNKNOWN, 0); } void btif_a2dp_source_cleanup(void) { // Make sure the source is shutdown btif_a2dp_source_shutdown(); btif_a2dp_source_thread.DoInThread( FROM_HERE, base::Bind(&btif_a2dp_source_cleanup_delayed)); // Exit the thread APPL_TRACE_EVENT("## A2DP SOURCE STOP MEDIA THREAD ##"); btif_a2dp_source_thread.ShutDown(); } static void btif_a2dp_source_cleanup_delayed(void) { // Nothing to do } bool btif_a2dp_source_media_task_is_running(void) { return (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateRunning); } Loading
system/btif/src/btif_av.cc +6 −6 Original line number Diff line number Diff line Loading @@ -822,8 +822,8 @@ bt_status_t BtifAvSource::Init( codec_priorities_ = codec_priorities; bta_av_co_init(codec_priorities_); if (!btif_a2dp_source_startup()) { return BT_STATUS_FAIL; // Already running if (!btif_a2dp_source_init()) { return BT_STATUS_FAIL; } btif_enable_service(BTA_A2DP_SOURCE_SERVICE_ID); enabled_ = true; Loading @@ -834,7 +834,7 @@ void BtifAvSource::Cleanup() { if (!enabled_) return; btif_queue_cleanup(UUID_SERVCLASS_AUDIO_SOURCE); do_in_jni_thread(FROM_HERE, base::Bind(&btif_a2dp_source_shutdown)); do_in_jni_thread(FROM_HERE, base::Bind(&btif_a2dp_source_cleanup)); btif_disable_service(BTA_A2DP_SOURCE_SERVICE_ID); CleanupAllPeers(); Loading Loading @@ -993,8 +993,8 @@ bt_status_t BtifAvSink::Init(btav_sink_callbacks_t* callbacks) { kDefaultMaxConnectedAudioDevices); callbacks_ = callbacks; if (!btif_a2dp_sink_startup()) { return BT_STATUS_FAIL; // Already running if (!btif_a2dp_sink_init()) { return BT_STATUS_FAIL; } btif_enable_service(BTA_A2DP_SINK_SERVICE_ID); enabled_ = true; Loading @@ -1005,7 +1005,7 @@ void BtifAvSink::Cleanup() { if (!enabled_) return; btif_queue_cleanup(UUID_SERVCLASS_AUDIO_SINK); do_in_jni_thread(FROM_HERE, base::Bind(&btif_a2dp_sink_shutdown)); do_in_jni_thread(FROM_HERE, base::Bind(&btif_a2dp_sink_cleanup)); btif_disable_service(BTA_A2DP_SINK_SERVICE_ID); CleanupAllPeers(); Loading