Stability fixes for a2dp hal control path

Ensure av statemachine is preventing a2dp hal to restart the stream
when not ready. This prevents ending up in a scenario where a2dp hal
locks up. Code cleanup.
bug 7002859

Change-Id: I3f3eeaab4ca185733b8b0042ed2cfa701f76a203
diff --git a/btif/include/btif_media.h b/btif/include/btif_media.h
old mode 100644
new mode 100755
index b3b72e7..55c88d5
--- a/btif/include/btif_media.h
+++ b/btif/include/btif_media.h
@@ -237,6 +237,7 @@
 void btif_a2dp_on_idle(void);
 void btif_a2dp_on_open(void);
 void btif_a2dp_on_started(tBTA_AV_START *p_av);
+void btif_a2dp_ack_fail(void);
 void btif_a2dp_on_stop_req(void);
 void btif_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av);
 void btif_a2dp_on_suspend(void);
diff --git a/btif/src/btif_av.c b/btif/src/btif_av.c
index 074164d..fbbd564 100755
--- a/btif/src/btif_av.c
+++ b/btif/src/btif_av.c
@@ -62,6 +62,8 @@
 
 #define BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING 0x1
 #define BTIF_AV_FLAG_REMOTE_SUSPEND        0x2
+#define BTIF_AV_FLAG_PENDING_START         0x4
+#define BTIF_AV_FLAG_PENDING_STOP          0x8
 
 /*****************************************************************************
 **  Local type definitions
@@ -401,6 +403,7 @@
             /* wait for audioflinger to stop a2dp */
             break;
 
+        case BTA_AV_STOP_EVT:
         case BTIF_AV_STOP_STREAM_REQ_EVT:
               /* immediately flush any pending tx frames while suspend is pending */
               btif_a2dp_set_tx_flush(TRUE);
@@ -462,15 +465,19 @@
     switch (event)
     {
         case BTIF_SM_ENTER_EVT:
+            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_STOP;
+            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
             btif_media_check_iop_exceptions(btif_av_cb.peer_bda.address);
-            break;
+             break;
 
         case BTIF_SM_EXIT_EVT:
+            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
             break;
 
         case BTIF_AV_START_STREAM_REQ_EVT:
             btif_a2dp_setup_codec();
             BTA_AvStart();
+            btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_START;
             break;
 
         case BTA_AV_START_EVT:
@@ -478,6 +485,7 @@
             BTIF_TRACE_EVENT3("BTA_AV_START_EVT status %d, suspending %d, init %d",
                 p_av->start.status, p_av->start.suspending, p_av->start.initiator);
 
+            btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
             if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE))
                 return TRUE;
 
@@ -502,6 +510,9 @@
 
         case BTA_AV_CLOSE_EVT:
 
+            /* avdtp link is closed */
+            btif_a2dp_on_stopped(NULL);
+
             /* inform the application that we are disconnected */
             HAL_CBACK(bt_av_callbacks, connection_state_cb,
                 BTAV_CONNECTION_STATE_DISCONNECTED, &(btif_av_cb.peer_bda));
@@ -509,6 +520,20 @@
             btif_sm_change_state(btif_av_cb.sm_handle, BTIF_AV_STATE_IDLE);
             break;
 
+        case BTA_AV_RECONFIG_EVT:
+            if((btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START) &&
+                (p_av->reconfig.status == BTA_AV_SUCCESS))
+            {
+               APPL_TRACE_WARNING0("reconfig done BTA_AVstart()");
+               BTA_AvStart();
+            }
+            else if(btif_av_cb.flags & BTIF_AV_FLAG_PENDING_START)
+            {
+               btif_av_cb.flags &= ~BTIF_AV_FLAG_PENDING_START;
+               btif_a2dp_ack_fail();
+            }
+            break;
+
         CHECK_RC_EVENT(event, p_data);
 
         default:
@@ -551,6 +576,11 @@
         case BTIF_SM_EXIT_EVT:
             break;
 
+        case BTIF_AV_START_STREAM_REQ_EVT:
+            /* we were remotely started, just ack back the local request */
+            btif_a2dp_on_started(NULL);
+            break;
+
         /* fixme -- use suspend = true always to work around issue with BTA AV */
         case BTIF_AV_STOP_STREAM_REQ_EVT:
         case BTIF_AV_SUSPEND_STREAM_REQ_EVT:
@@ -627,6 +657,8 @@
 
         case BTA_AV_STOP_EVT:
 
+            btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
+
             btif_a2dp_on_stopped(&p_av->suspend);
 
             HAL_CBACK(bt_av_callbacks, audio_state_cb,
@@ -640,6 +672,8 @@
 
         case BTA_AV_CLOSE_EVT:
 
+             btif_av_cb.flags |= BTIF_AV_FLAG_PENDING_STOP;
+
             /* avdtp link is closed */
 
             btif_a2dp_on_stopped(NULL);
@@ -854,8 +888,8 @@
         return FALSE;
     }
 
-    /* check if we are remotely suspended */
-    if (btif_av_cb.flags & BTIF_AV_FLAG_REMOTE_SUSPEND)
+    /* check if we are remotely suspended or stop is pending */
+    if (btif_av_cb.flags & (BTIF_AV_FLAG_REMOTE_SUSPEND|BTIF_AV_FLAG_PENDING_STOP))
         return FALSE;
 
     return (state == BTIF_AV_STATE_OPENED);
@@ -878,9 +912,9 @@
     BTIF_TRACE_DEBUG3("btif_av_stream_started : sm hdl %d, state %d, flags %x",
                 btif_av_cb.sm_handle, state, btif_av_cb.flags);
 
-    /* don't allow media task to start if we are suspending or
-       remotely suspended (not yet changed state) */
-    if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND))
+    /* disallow media task to start if we have pending actions */
+    if (btif_av_cb.flags & (BTIF_AV_FLAG_LOCAL_SUSPEND_PENDING | BTIF_AV_FLAG_REMOTE_SUSPEND
+        | BTIF_AV_FLAG_PENDING_STOP))
         return FALSE;
 
     return (state == BTIF_AV_STATE_STARTED);
@@ -958,11 +992,11 @@
 
 /*******************************************************************************
 **
-** Function         btif_av_is_rc_open_without_a2dp
+** Function         btif_av_is_connected
 **
-** Description      Checks if GAVDTP Open notification to app is pending (2 second timer)
+** Description      Checks if av has a connected sink
 **
-** Returns          boolean
+** Returns          BOOLEAN
 **
 *******************************************************************************/
 BOOLEAN btif_av_is_connected(void)
diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c
index 200cf06..3c15b27 100755
--- a/btif/src/btif_media_task.c
+++ b/btif/src/btif_media_task.c
@@ -35,6 +35,7 @@
 #include <pthread.h>
 #include <stdint.h>
 #include <sys/time.h>
+#include <errno.h>
 
 #include "bt_target.h"
 #include "gki.h"
@@ -51,11 +52,9 @@
 #include "bta_av_ci.h"
 #include "l2c_api.h"
 
-
 #include "btif_av_co.h"
 #include "btif_media.h"
 
-
 #if (BTA_AV_INCLUDED == TRUE)
 #include "sbc_encoder.h"
 #endif
@@ -166,7 +165,7 @@
 #define BT_MEDIA_TASK A2DP_MEDIA_TASK
 
 #define USEC_PER_SEC 1000000L
-#define TPUT_STATS_INTERVAL_US (1000*1000)
+#define TPUT_STATS_INTERVAL_US (3000*1000)
 
 /*
  * CONGESTION COMPENSATION CTRL ::
@@ -234,11 +233,11 @@
 } tBTIF_MEDIA_CB;
 
 typedef struct {
-    int rx;
-    int rx_tot;
-    int tx;
-    int tx_tot;
-    int ts_prev_us;
+    long long rx;
+    long long rx_tot;
+    long long tx;
+    long long tx_tot;
+    long long ts_prev_us;
 } t_stat;
 
 /*****************************************************************************
@@ -256,6 +255,7 @@
 static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
 static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event);
 static void btif_a2dp_encoder_update(void);
+const char* dump_media_event(UINT16 event);
 
 /*****************************************************************************
  **  Externs
@@ -286,8 +286,8 @@
     /* only monitor one connection at a time for now */
     static t_stat cur_stat;
     struct timespec now;
-    unsigned int prev_us;
-    unsigned int now_us;
+    unsigned long long prev_us;
+    unsigned long long now_us;
 
     if (reset == TRUE)
     {
@@ -309,14 +309,12 @@
 
     now_us = now.tv_sec*USEC_PER_SEC + now.tv_nsec/1000;
 
-    //APPL_TRACE_DEBUG1("%d us", now_us - cur_stat.ts_prev_us);
-
     if ((now_us - cur_stat.ts_prev_us) < TPUT_STATS_INTERVAL_US)
         return;
 
-    APPL_TRACE_WARNING4("tput rx:%d, tx:%d (kB/s)  (tot : rx %d, tx %d bytes)",
-          (cur_stat.rx)/((now_us - cur_stat.ts_prev_us)/1000),
-          (cur_stat.tx)/((now_us - cur_stat.ts_prev_us)/1000),
+    APPL_TRACE_WARNING4("tput rx:%d, tx:%d (bytes/s)  (tot : rx %d, tx %d bytes)",
+          (cur_stat.rx*1000000)/((now_us - cur_stat.ts_prev_us)),
+          (cur_stat.tx*1000000)/((now_us - cur_stat.ts_prev_us)),
            cur_stat.rx_tot, cur_stat.tx_tot);
 
     /* stats dumped. now reset stats for next interval */
@@ -401,7 +399,8 @@
 {
     UINT8 ack = status;
 
-    APPL_TRACE_EVENT2("## a2dp ack : %s, status %d ##", dump_a2dp_ctrl_event(btif_media_cb.a2dp_cmd_pending), status);
+    APPL_TRACE_EVENT2("## a2dp ack : %s, status %d ##",
+          dump_a2dp_ctrl_event(btif_media_cb.a2dp_cmd_pending), status);
 
     /* sanity check */
     if (btif_media_cb.a2dp_cmd_pending == A2DP_CTRL_CMD_NONE)
@@ -838,11 +837,17 @@
 
 void btif_a2dp_on_started(tBTA_AV_START *p_av)
 {
-    tBTIF_AV_MEDIA_FEEDINGS media_feeding;
     tBTIF_STATUS status;
 
     APPL_TRACE_EVENT0("## ON A2DP STARTED ##");
 
+    if (p_av == NULL)
+    {
+        /* ack back a local start request */
+        a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
+        return;
+    }
+
     if (p_av->status == BTA_AV_SUCCESS)
     {
         if (p_av->suspending == FALSE)
@@ -870,6 +875,24 @@
 
 /*****************************************************************************
 **
+** Function        btif_a2dp_ack_fail
+**
+** Description
+**
+** Returns
+**
+*******************************************************************************/
+
+void btif_a2dp_ack_fail(void)
+{
+    tBTIF_STATUS status;
+
+    APPL_TRACE_EVENT0("## A2DP_CTRL_ACK_FAILURE ##");
+    a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
+}
+
+/*****************************************************************************
+**
 ** Function        btif_a2dp_on_stopped
 **
 ** Description
@@ -1182,7 +1205,8 @@
  *******************************************************************************/
 static void btif_media_task_handle_cmd(BT_HDR *p_msg)
 {
-    VERBOSE("btif_media_task_handle_cmd : %d %s", p_msg->event, dump_media_event(p_msg->event));
+    VERBOSE("btif_media_task_handle_cmd : %d %s", p_msg->event,
+             dump_media_event(p_msg->event));
 
     switch (p_msg->event)
     {
@@ -1467,7 +1491,8 @@
     /* Only update the bitrate and MTU size while timer is running to make sure it has been initialized */
     //if (btif_media_cb.is_tx_timer)
     {
-        btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET - sizeof(BT_HDR))
+        btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE -
+                                      BTIF_MEDIA_AA_SBC_OFFSET - sizeof(BT_HDR))
                 < pUpdateAudio->MinMtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_SBC_OFFSET
                 - sizeof(BT_HDR)) : pUpdateAudio->MinMtuSize;
 
@@ -1533,11 +1558,13 @@
                 s16BitPool = 0;
             }
 
-            APPL_TRACE_EVENT2("bitpool candidate : %d (%d kbps)", s16BitPool, pstrEncParams->u16BitRate);
+            APPL_TRACE_EVENT2("bitpool candidate : %d (%d kbps)",
+                         s16BitPool, pstrEncParams->u16BitRate);
 
             if (s16BitPool > pUpdateAudio->MaxBitPool)
             {
-                APPL_TRACE_WARNING1("btif_media_task_enc_update computed bitpool too large (%d)", s16BitPool);
+                APPL_TRACE_DEBUG1("btif_media_task_enc_update computed bitpool too large (%d)",
+                                    s16BitPool);
                 /* Decrease bitrate */
                 btif_media_cb.encoder.u16BitRate -= BTIF_MEDIA_BITRATE_STEP;
                 /* Record that we have decreased the bitrate */
@@ -1592,7 +1619,6 @@
     APPL_TRACE_DEBUG1("num_channel:%d", p_feeding->feeding.cfg.pcm.num_channel);
     APPL_TRACE_DEBUG1("bit_per_sample:%d", p_feeding->feeding.cfg.pcm.bit_per_sample);
 
-
     /* Check the PCM feeding sampling_freq */
     switch (p_feeding->feeding.cfg.pcm.sampling_freq)
     {
@@ -1639,11 +1665,13 @@
 
     if (reconfig_needed != FALSE)
     {
-        APPL_TRACE_DEBUG0("btif_media_task_pcm2sbc_init calls SBC_Encoder_Init");
-        APPL_TRACE_DEBUG1("btif_media_task_pcm2sbc_init mtu %d", btif_media_cb.TxAaMtuSize);
-        APPL_TRACE_DEBUG6("btif_media_task_pcm2sbc_init ch mode %d, nbsubd %d, nb blk %d, alloc method %d, bit rate %d, Smp freq %d",
-                btif_media_cb.encoder.s16ChannelMode, btif_media_cb.encoder.s16NumOfSubBands, btif_media_cb.encoder.s16NumOfBlocks,
-                btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate, btif_media_cb.encoder.s16SamplingFreq);
+        APPL_TRACE_DEBUG1("btif_media_task_pcm2sbc_init :: mtu %d", btif_media_cb.TxAaMtuSize);
+        APPL_TRACE_DEBUG6("ch mode %d, nbsubd %d, nb %d, alloc %d, rate %d, freq %d",
+                btif_media_cb.encoder.s16ChannelMode,
+                btif_media_cb.encoder.s16NumOfSubBands, btif_media_cb.encoder.s16NumOfBlocks,
+                btif_media_cb.encoder.s16AllocationMethod, btif_media_cb.encoder.u16BitRate,
+                btif_media_cb.encoder.s16SamplingFreq);
+
         SBC_Encoder_Init(&(btif_media_cb.encoder));
     }
     else
@@ -1740,8 +1768,7 @@
 static void btif_media_task_aa_start_tx(void)
 {
     APPL_TRACE_DEBUG2("btif_media_task_aa_start_tx is timer %d, feeding mode %d",
-            btif_media_cb.is_tx_timer, btif_media_cb.feeding_mode);
-
+             btif_media_cb.is_tx_timer, btif_media_cb.feeding_mode);
 
     /* Use a timer to poll the UIPC, get rid of the UIPC call back */
     // UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_CBACK, NULL);
@@ -1751,7 +1778,9 @@
     /* Reset the media feeding state */
     btif_media_task_feeding_state_reset();
 
-    APPL_TRACE_EVENT2("starting timer %d ticks (%d)", GKI_MS_TO_TICKS(BTIF_MEDIA_TIME_TICK), TICKS_PER_SEC);
+    APPL_TRACE_EVENT2("starting timer %d ticks (%d)",
+                  GKI_MS_TO_TICKS(BTIF_MEDIA_TIME_TICK), TICKS_PER_SEC);
+
     GKI_start_timer(BTIF_MEDIA_AA_TASK_TIMER_ID, GKI_MS_TO_TICKS(BTIF_MEDIA_TIME_TICK), TRUE);
 }
 
@@ -1790,8 +1819,6 @@
  ** Returns          The number of media frames in this time slice
  **
  *******************************************************************************/
-
-
 static UINT8 btif_get_num_aa_frame(void)
 {
     UINT8 result=0;
@@ -1886,12 +1913,13 @@
 BOOLEAN btif_media_aa_read_feeding(tUIPC_CH_ID channel_id)
 {
     UINT16 event;
-    /* coverity[SIGN_EXTENSION] False-positive: Parameter are always in range avoiding sign extension*/
-    UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands * btif_media_cb.encoder.s16NumOfBlocks;
+    UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands * \
+                             btif_media_cb.encoder.s16NumOfBlocks;
     UINT32 read_size;
     UINT16 sbc_sampling = 48000;
     UINT32 src_samples;
-    UINT16 bytes_needed = blocm_x_subband * btif_media_cb.encoder.s16NumOfChannels * sizeof(SINT16);
+    UINT16 bytes_needed = blocm_x_subband * btif_media_cb.encoder.s16NumOfChannels * \
+                          sizeof(SINT16);
     static UINT16 up_sampled_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
             * SBC_MAX_NUM_OF_CHANNELS * SBC_MAX_NUM_OF_SUBBANDS * 2];
     static UINT16 read_buffer[SBC_MAX_NUM_FRAME * SBC_MAX_NUM_OF_BLOCKS
@@ -1992,7 +2020,7 @@
             btif_media_cb.media_feeding.cfg.pcm.num_channel);
 
     /* re-sample read buffer */
-    /* The output PCM buffer will be stereo, 16 bit per sec */
+    /* The output PCM buffer will be stereo, 16 bit per sample */
     dst_size_used = bta_av_sbc_up_sample((UINT8 *)read_buffer,
             (UINT8 *)up_sampled_buffer + btif_media_cb.media_feeding_state.pcm.aa_feed_residue,
             nb_byte_read,
@@ -2000,7 +2028,7 @@
             &src_size_used);
 
 #if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
-    APPL_TRACE_DEBUG3("btif_media_aa_read_feeding read_size:%d src_size_used:%d dst_size_used:%d",
+    APPL_TRACE_DEBUG3("btif_media_aa_read_feeding readsz:%d src_size_used:%d dst_size_used:%d",
             read_size, src_size_used, dst_size_used);
 #endif
 
@@ -2046,16 +2074,19 @@
 static void btif_media_aa_prep_sbc_2_send(UINT8 nb_frame)
 {
     BT_HDR * p_buf;
-    UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands * btif_media_cb.encoder.s16NumOfBlocks;
+    UINT16 blocm_x_subband = btif_media_cb.encoder.s16NumOfSubBands *
+                             btif_media_cb.encoder.s16NumOfBlocks;
 
 #if (defined(DEBUG_MEDIA_AV_FLOW) && (DEBUG_MEDIA_AV_FLOW == TRUE))
-    APPL_TRACE_DEBUG2("btif_media_aa_prep_sbc_2_send nb_frame %d, TxAaQ %d", nb_frame, btif_media_cb.TxAaQ.count);
+    APPL_TRACE_DEBUG2("btif_media_aa_prep_sbc_2_send nb_frame %d, TxAaQ %d",
+                       nb_frame, btif_media_cb.TxAaQ.count);
 #endif
     while (nb_frame)
     {
         if (NULL == (p_buf = GKI_getpoolbuf(BTIF_MEDIA_AA_POOL_ID)))
         {
-            APPL_TRACE_ERROR1 ("ERROR btif_media_aa_prep_sbc_2_send no buffer TxCnt %d ", btif_media_cb.TxAaQ.count);
+            APPL_TRACE_ERROR1 ("ERROR btif_media_aa_prep_sbc_2_send no buffer TxCnt %d ",
+                                btif_media_cb.TxAaQ.count);
             return;
         }
 
@@ -2069,7 +2100,6 @@
             /* Write @ of allocated buffer in encoder.pu8Packet */
             btif_media_cb.encoder.pu8Packet = (UINT8 *) (p_buf + 1) + p_buf->offset + p_buf->len;
             /* Fill allocated buffer with 0 */
-            /* coverity[SIGN_EXTENSION] False-positive: Parameter are always in range avoiding sign extension*/
             memset(btif_media_cb.encoder.as16PcmBuffer, 0, blocm_x_subband
                     * btif_media_cb.encoder.s16NumOfChannels);
 
@@ -2100,11 +2130,12 @@
 
         if(p_buf->len)
         {
-            btif_media_cb.timestamp += p_buf->layer_specific * blocm_x_subband;
-
-            /* store the time stamp in the buffer to send */
+            /* timestamp of the media packet header represent the TS of the first SBC frame
+               i.e the timestamp before including this frame */
             *((UINT32 *) (p_buf + 1)) = btif_media_cb.timestamp;
 
+            btif_media_cb.timestamp += p_buf->layer_specific * blocm_x_subband;
+
             VERBOSE("TX QUEUE NOW %d", btif_media_cb.TxAaQ.count);
 
             if (btif_media_cb.tx_flush)