aboutsummaryrefslogtreecommitdiff
path: root/udrv
diff options
context:
space:
mode:
authorHansong Zhang <hsz@google.com>2018-02-01 18:02:53 -0800
committerPavlin Radoslavov <pavlin@google.com>2018-02-14 05:11:46 +0000
commitf88552cdd8360cc3a28e4f7e10101b6859692c69 (patch)
tree2049496b212b7b071447569cce9af06b14c31a02 /udrv
parent37a143f49aeb9f3fdc452c6e7f8f5fe72043363b (diff)
downloadbt-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.h97
-rw-r--r--udrv/ulinux/uipc.cc31
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");