More work on A2DP Sink:

Output audio data through A2DP audio HAL rather than playing directly
to native AudioTrack API.

Add separate HAL interface for A2DP sink

Change-Id: I6c6cb6088c350e104b4a7354f328b29c7178e295
diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c
index e45ddfc..7e29917 100644
--- a/btif/src/btif_media_task.c
+++ b/btif/src/btif_media_task.c
@@ -72,7 +72,6 @@
 #endif
 #include "stdio.h"
 #include <dlfcn.h>
-#include "bluetoothTrack.h"
 
 //#define DEBUG_MEDIA_AV_FLOW TRUE
 
@@ -279,9 +278,12 @@
     UINT8 a2dp_cmd_pending; /* we can have max one command pending */
     BOOLEAN tx_flush; /* discards any outgoing data when true */
     BOOLEAN rx_flush; /* discards any incoming data when true */
-    BOOLEAN is_source;
+    UINT8 peer_sep;
+    BOOLEAN data_channel_open;
     UINT8   frames_to_process;
-    BOOLEAN rx_audio_focus_gained;
+
+    UINT32  sample_rate;
+    UINT8   channel_count;
 #endif
 
 } tBTIF_MEDIA_CB;
@@ -355,7 +357,6 @@
 #endif
 static void btif_media_task_aa_handle_start_decoding(void );
 #endif
-extern void btif_av_request_audio_focus(BOOLEAN enable);
 BOOLEAN btif_media_task_start_decoding_req(void);
 BOOLEAN btif_media_task_clear_track(void);
 /*****************************************************************************
@@ -510,6 +511,8 @@
 
                 /* post start event and wait for audio path to open */
                 btif_dispatch_sm_event(BTIF_AV_START_STREAM_REQ_EVT, NULL, 0);
+//FIXME
+                a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
             }
             else if (btif_av_stream_started_ready())
             {
@@ -527,8 +530,7 @@
             break;
 
         case A2DP_CTRL_CMD_STOP:
-
-            if (btif_media_cb.is_tx_timer == FALSE)
+            if (btif_media_cb.peer_sep == AVDT_TSEP_SNK && btif_media_cb.is_tx_timer == FALSE)
             {
                 /* we are already stopped, just ack back */
                 a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
@@ -536,6 +538,7 @@
             }
 
             btif_dispatch_sm_event(BTIF_AV_STOP_STREAM_REQ_EVT, NULL, 0);
+            a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
             break;
 
         case A2DP_CTRL_CMD_SUSPEND:
@@ -553,6 +556,17 @@
             }
             break;
 
+        case A2DP_CTRL_GET_AUDIO_CONFIG:
+        {
+            uint32_t sample_rate = btif_media_cb.sample_rate;
+            uint8_t channel_count = btif_media_cb.channel_count;
+
+            a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
+            UIPC_Send(UIPC_CH_ID_AV_CTRL, 0, (UINT8 *)&sample_rate, 4);
+            UIPC_Send(UIPC_CH_ID_AV_CTRL, 0, &channel_count, 1);
+            break;
+        }
+
         default:
             APPL_TRACE_ERROR1("UNSUPPORTED CMD (%d)", cmd);
             a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE);
@@ -605,11 +619,15 @@
             UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
             UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
                        (void *)A2DP_DATA_READ_POLL_MS);
-            /* Start the media task to encode SBC */
-            btif_media_task_start_aa_req();
 
-            /* make sure we update any changed sbc encoder params */
-            btif_a2dp_encoder_update();
+            if (btif_media_cb.peer_sep == AVDT_TSEP_SNK) {
+                /* Start the media task to encode SBC */
+                btif_media_task_start_aa_req();
+
+                /* make sure we update any changed sbc encoder params */
+                btif_a2dp_encoder_update();
+            }
+            btif_media_cb.data_channel_open = TRUE;
 
             /* ack back when media task is fully started */
             break;
@@ -617,6 +635,7 @@
         case UIPC_CLOSE_EVT:
             a2dp_cmd_acknowledge(A2DP_CTRL_ACK_SUCCESS);
             btif_audiopath_detached();
+            btif_media_cb.data_channel_open = FALSE;
             break;
 
         default :
@@ -860,7 +879,7 @@
 void btif_a2dp_on_idle(void)
 {
     APPL_TRACE_EVENT0("## ON A2DP IDLE ##");
-    if(btif_media_cb.is_source)
+    if (btif_media_cb.peer_sep == AVDT_TSEP_SNK)
     {
         /* Make sure media task is stopped */
         btif_media_task_stop_aa_req();
@@ -868,16 +887,13 @@
 
     bta_av_co_init();
 #ifdef BTA_AVK_INCLUDED
-    if (!btif_media_cb.is_source)
+    if (btif_media_cb.peer_sep == AVDT_TSEP_SRC)
     {
         btif_media_cb.rx_flush = TRUE;
         btif_media_task_aa_rx_flush_req();
         btif_media_task_stop_decoding_req();
         btif_media_task_clear_track();
         APPL_TRACE_DEBUG0("Stopped BT track");
-        APPL_TRACE_DEBUG0("Reset to Source role");
-        btif_media_cb.is_source = TRUE;
-        btif_media_cb.rx_audio_focus_gained = BTIF_MEDIA_AUDIOFOCUS_LOSS;
     }
 #endif
 }
@@ -1092,11 +1108,13 @@
 void btif_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av)
 {
     APPL_TRACE_EVENT0("## ON A2DP STOPPED ##");
-    if ((!btif_media_cb.is_source)) /*  Handling for A2DP SINK cases*/
+    if (btif_media_cb.peer_sep == AVDT_TSEP_SRC) /*  Handling for A2DP SINK cases*/
     {
         btif_media_cb.rx_flush = TRUE;
         btif_media_task_aa_rx_flush_req();
         btif_media_task_stop_decoding_req();
+        UIPC_Close(UIPC_CH_ID_AV_AUDIO);
+        btif_media_cb.data_channel_open = FALSE;
         return;
     }
     /* allow using this api for other than suspend */
@@ -1136,7 +1154,7 @@
 void btif_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av)
 {
     APPL_TRACE_EVENT0("## ON A2DP SUSPENDED ##");
-    if ((!btif_media_cb.is_source))
+    if (btif_media_cb.peer_sep == AVDT_TSEP_SRC)
     {
         btif_media_cb.rx_flush = TRUE;
         btif_media_task_aa_rx_flush_req();
@@ -1174,13 +1192,6 @@
     btif_media_cb.tx_flush = enable;
 }
 
-/* when true media task discards any rx frames */
-void btif_a2dp_set_audio_focus_state(btif_media_AudioFocus_state state)
-{
-    APPL_TRACE_EVENT1("## Audio_focus_state Rx %d ##", state);
-    btif_media_cb.rx_audio_focus_gained = state;
-}
-
 #ifdef BTA_AVK_INCLUDED
 /*******************************************************************************
  **
@@ -1210,18 +1221,7 @@
             btif_media_flush_q(&(btif_media_cb.RxSbcQ));
             return;
         }
-        if (btif_media_cb.rx_audio_focus_gained == BTIF_MEDIA_AUDIOFOCUS_LOSS_TRANSIENT)
-        {
-            APPL_TRACE_DEBUG0("Received Transient Focus Loss, Ignoring");
-            return;
-        }
 
-        if (btif_media_cb.rx_audio_focus_gained == BTIF_MEDIA_AUDIOFOCUS_LOSS)
-        {
-            /* Send a Audio Focus Request */
-            btif_av_request_audio_focus(TRUE);
-            return;
-        }
         num_frames_to_process = btif_media_cb.frames_to_process;
         APPL_TRACE_DEBUG0(" Process Frames + ");
 
@@ -1338,8 +1338,6 @@
 #if (BTA_AV_INCLUDED == TRUE)
     UIPC_Open(UIPC_CH_ID_AV_CTRL , btif_a2dp_ctrl_cb);
 #endif
-    btif_media_cb.is_source = TRUE;
-    APPL_TRACE_DEBUG0("Reset to Source role");
 }
 /*******************************************************************************
  **
@@ -1558,14 +1556,18 @@
     OI_STATUS status;
     int num_sbc_frames = p_msg->num_frames_to_be_processed;
     UINT32 sbc_frame_len = p_msg->len - 1;
-    int retwriteAudioTrack = 0;
     availPcmBytes = 2*sizeof(pcmData);
 
-    if ((btif_media_cb.is_source) || (btif_media_cb.rx_flush))
+    if ((btif_media_cb.peer_sep == AVDT_TSEP_SNK) || (btif_media_cb.rx_flush))
     {
         APPL_TRACE_DEBUG0(" State Changed happened in this tick ");
         return;
     }
+
+    // ignore data if no one is listening
+    if (!btif_media_cb.data_channel_open)
+        return;
+
     APPL_TRACE_DEBUG2("Number of sbc frames %d, frame_len %d", num_sbc_frames, sbc_frame_len);
 
     for(count = 0; count < num_sbc_frames && sbc_frame_len != 0; count ++)
@@ -1585,7 +1587,7 @@
         p_msg->len = sbc_frame_len + 1;
     }
 
-    retwriteAudioTrack = btWriteData((void*)pcmData, (2*sizeof(pcmData) - availPcmBytes));
+    UIPC_Send(UIPC_CH_ID_AV_AUDIO, 0, (UINT8 *)pcmData, (2*sizeof(pcmData) - availPcmBytes));
 }
 #endif
 
@@ -2107,7 +2109,7 @@
     }
 }
 
-int a2dp_get_track_frequency(UINT8 frequency) {
+int btif_a2dp_get_track_frequency(UINT8 frequency) {
     int freq = 48000;
     switch (frequency) {
         case A2D_SBC_IE_SAMP_FREQ_16:
@@ -2126,19 +2128,23 @@
     return freq;
 }
 
-int a2dp_get_track_channel_type(UINT8 channeltype) {
-    int channel = AUDIO_CHANNEL_OUT_MONO;
+int btif_a2dp_get_track_channel_count(UINT8 channeltype) {
+    int count = 1;
     switch (channeltype) {
         case A2D_SBC_IE_CH_MD_MONO:
-            channel = AUDIO_CHANNEL_OUT_MONO;
+            count = 1;
             break;
         case A2D_SBC_IE_CH_MD_DUAL:
         case A2D_SBC_IE_CH_MD_STEREO:
         case A2D_SBC_IE_CH_MD_JOINT:
-            channel = AUDIO_CHANNEL_OUT_STEREO;
+            count = 2;
             break;
     }
-    return channel;
+    return count;
+}
+
+void btif_a2dp_set_peer_sep(UINT8 sep) {
+    btif_media_cb.peer_sep = sep;
 }
 
 /*******************************************************************************
@@ -2154,7 +2160,6 @@
 {
     btif_media_cb.is_rx_timer = FALSE;
     GKI_stop_timer(BTIF_MEDIA_AVK_TASK_TIMER_ID);
-    btPauseTrack();
 }
 
 /*******************************************************************************
@@ -2170,7 +2175,6 @@
 {
     if(btif_media_cb.is_rx_timer == TRUE)
         return;
-    btStartTrack();
     btif_media_cb.is_rx_timer = TRUE;
     GKI_start_timer(BTIF_MEDIA_AVK_TASK_TIMER_ID, GKI_MS_TO_TICKS(BTIF_SINK_MEDIA_TIME_TICK), TRUE);
 }
@@ -2180,8 +2184,6 @@
 static void btif_media_task_aa_handle_clear_track (void)
 {
     APPL_TRACE_DEBUG0("btif_media_task_aa_handle_clear_track");
-    btStopTrack();
-    btDeleteTrack();
 }
 
 /*******************************************************************************
@@ -2213,18 +2215,18 @@
         APPL_TRACE_ERROR1("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d", a2d_status);
         return;
     }
-    btif_media_cb.is_source = FALSE;
+
+    btif_media_cb.sample_rate = btif_a2dp_get_track_frequency(sbc_cie.samp_freq);
+    btif_media_cb.channel_count = btif_a2dp_get_track_channel_count(sbc_cie.ch_mode);
+
     btif_media_cb.rx_flush = FALSE;
     APPL_TRACE_DEBUG0("Reset to sink role");
     status = OI_CODEC_SBC_DecoderReset(&context, contextData, sizeof(contextData), 2, 2, FALSE);
     if (!OI_SUCCESS(status)) {
         APPL_TRACE_ERROR1("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
     }
-    APPL_TRACE_DEBUG0("A2dpSink: Crate Track");
-    if (btCreateTrack(a2dp_get_track_frequency(sbc_cie.samp_freq), a2dp_get_track_channel_type(sbc_cie.ch_mode)) == -1) {
-        APPL_TRACE_ERROR0("A2dpSink: Track creation fails!!!");
-        return;
-    }
+
+    UIPC_Open(UIPC_CH_ID_AV_AUDIO, btif_a2dp_data_cb);
 
     switch(sbc_cie.samp_freq)
     {