diff options
author | Hansong Zhang <hsz@google.com> | 2018-02-01 18:02:53 -0800 |
---|---|---|
committer | Pavlin Radoslavov <pavlin@google.com> | 2018-02-14 05:11:46 +0000 |
commit | f88552cdd8360cc3a28e4f7e10101b6859692c69 (patch) | |
tree | 2049496b212b7b071447569cce9af06b14c31a02 /udrv | |
parent | 37a143f49aeb9f3fdc452c6e7f8f5fe72043363b (diff) | |
download | bt-f88552cdd8360cc3a28e4f7e10101b6859692c69.tar.gz |
A2DP: Cleanup UIPC when no active device
* Modified UIPC to support multiple users
* A2DP now calls UIPC_Close() when it has no active device, and calls
UIPC_Init() when it has an active device
Bug: 72701090
Test: Carkits with A2DP
Change-Id: Ic1b4b1be2aa01c9896883e3cb2a668d7a43316f9
Diffstat (limited to 'udrv')
-rw-r--r-- | udrv/include/uipc.h | 97 | ||||
-rw-r--r-- | udrv/ulinux/uipc.cc | 31 |
2 files changed, 75 insertions, 53 deletions
diff --git a/udrv/include/uipc.h b/udrv/include/uipc.h index fb956b534..332becaac 100644 --- a/udrv/include/uipc.h +++ b/udrv/include/uipc.h @@ -37,6 +37,13 @@ typedef enum { UIPC_TX_DATA_READY_EVT = 0x0010 } tUIPC_EVENT; +/* UIPC users */ +typedef enum { + UIPC_USER_A2DP = 0, + UIPC_USER_HEARING_AID = 1, + UIPC_USER_NUM = 2 +} tUIPC_USER; + /* * UIPC IOCTL Requests */ @@ -55,72 +62,62 @@ typedef void(tUIPC_RCV_CBACK)( const char* dump_uipc_event(tUIPC_EVENT event); -/******************************************************************************* - * - * Function UIPC_Init - * - * Description Initialize UIPC module +/** + * Initialize UIPC module * - * Returns void - * - ******************************************************************************/ -void UIPC_Init(void*); + * @param user User ID who uses UIPC + */ +void UIPC_Init(void*, int user); -/******************************************************************************* - * - * Function UIPC_Open +/** + * Open a UIPC channel * - * Description Open UIPC interface - * - * Returns void - * - ******************************************************************************/ + * @param ch_id Channel ID + * @param p_cback Callback handler + * @return true on success, otherwise false + */ bool UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK* p_cback); -/******************************************************************************* +/** + * Closes a channel in UIPC or the entire UIPC module * - * Function UIPC_Close - * - * Description Close UIPC interface - * - * Returns void - * - ******************************************************************************/ -void UIPC_Close(tUIPC_CH_ID ch_id); + * @param ch_id Channel ID; if ch_id is UIPC_CH_ID_ALL, then cleanup UIPC + * @param user User ID who uses UIPC + */ +void UIPC_Close(tUIPC_CH_ID ch_id, int user); -/******************************************************************************* - * - * Function UIPC_Send - * - * Description Called to transmit a message over UIPC. - * - * Returns void +/** + * Send a message over UIPC * - ******************************************************************************/ + * @param ch_id Channel ID + * @param msg_evt Message event type + * @param p_buf Buffer for the message + * @param msglen Message length + * @return true on success, otherwise false + */ bool UIPC_Send(tUIPC_CH_ID ch_id, uint16_t msg_evt, const uint8_t* p_buf, uint16_t msglen); -/******************************************************************************* - * - * Function UIPC_Read - * - * Description Called to read a message from UIPC. +/** + * Read a message from UIPC * - * Returns void - * - ******************************************************************************/ + * @param ch_id Channel ID + * @param p_msg_evt Message event type + * @param p_buf Buffer for the message + * @param len Bytes to read + * @return true on success, otherwise false + */ uint32_t UIPC_Read(tUIPC_CH_ID ch_id, uint16_t* p_msg_evt, uint8_t* p_buf, uint32_t len); -/******************************************************************************* - * - * Function UIPC_Ioctl +/** + * Control the UIPC parameter * - * Description Called to control UIPC. - * - * Returns void - * - ******************************************************************************/ + * @param ch_id Channel ID + * @param request Request type + * @param param Optional parameters + * @return true on success, otherwise false + */ bool UIPC_Ioctl(tUIPC_CH_ID ch_id, uint32_t request, void* param); #endif /* UIPC_H */ diff --git a/udrv/ulinux/uipc.cc b/udrv/ulinux/uipc.cc index 63a7fb0d5..78fdac8dd 100644 --- a/udrv/ulinux/uipc.cc +++ b/udrv/ulinux/uipc.cc @@ -39,6 +39,7 @@ #include <sys/un.h> #include <unistd.h> #include <mutex> +#include <set> #include "audio_a2dp_hw/include/audio_a2dp_hw.h" #include "bt_common.h" @@ -93,6 +94,7 @@ typedef struct { int signal_fds[2]; tUIPC_CHAN ch[UIPC_CH_NUM]; + std::set<int> active_users; } tUIPC_MAIN; /***************************************************************************** @@ -247,6 +249,8 @@ void uipc_main_cleanup(void) { /* close any open channels */ for (i = 0; i < UIPC_CH_NUM; i++) uipc_close_ch_locked(i); + + uipc_main.active_users.clear(); } /* check pending events in read task */ @@ -548,8 +552,17 @@ void uipc_stop_main_server_thread(void) { ** ******************************************************************************/ -void UIPC_Init(UNUSED_ATTR void* p_data) { +void UIPC_Init(UNUSED_ATTR void* p_data, int user) { BTIF_TRACE_DEBUG("UIPC_Init"); + if (user < 0 || user >= UIPC_USER_NUM) { + BTIF_TRACE_ERROR("UIPC_Close : invalid user ID %d", user); + return; + } + std::lock_guard<std::recursive_mutex> lock(uipc_main.mutex); + auto result_insert = uipc_main.active_users.insert(user); + if ((uipc_main.active_users.size() != 1) || !result_insert.second) { + return; + } uipc_main_init(); uipc_start_main_server_thread(); @@ -601,15 +614,27 @@ bool UIPC_Open(tUIPC_CH_ID ch_id, tUIPC_RCV_CBACK* p_cback) { ** ******************************************************************************/ -void UIPC_Close(tUIPC_CH_ID ch_id) { +void UIPC_Close(tUIPC_CH_ID ch_id, int user) { BTIF_TRACE_DEBUG("UIPC_Close : ch_id %d", ch_id); - + if (user < 0 || user >= UIPC_USER_NUM) { + BTIF_TRACE_ERROR("UIPC_Close : invalid user ID %d", user); + return; + } /* special case handling uipc shutdown */ if (ch_id != UIPC_CH_ID_ALL) { std::lock_guard<std::recursive_mutex> lock(uipc_main.mutex); uipc_close_locked(ch_id); return; } + + if (uipc_main.active_users.erase(user) == 0) { + return; + } + + if (!uipc_main.active_users.empty()) { + return; + } + BTIF_TRACE_DEBUG("UIPC_Close : waiting for shutdown to complete"); uipc_stop_main_server_thread(); BTIF_TRACE_DEBUG("UIPC_Close : shutdown complete"); |