BATestApp: Refactoring BATestApp and BATService.

This change removes framework dependency required for BATestApp
and BATService. To achieve the same, existing code of BATestApp
and BATService is refactored.

- Added Security Parameters for intents so that receivers with BT Admin permission can only receive it.
- Removed unnecessary logs.
- Removed Parcelable implementation.
- Removed StreamID and DIV implementation from BAAudio.java.
- Removed BATService Listener Class and getProfileProxy() implementation from BAAudio.java.
- Implemented a 30 sec timeout for Enabling BA in BAAudio.java
- Removed the ACTION_BLE_STATE_CHANGED intent and processBTStateChanged() implementation from GattBroadcastService.java.
- Removed extra intent variables, updated value of isStateChangePending in case of BT timeout scenario.
- Added functionality for ACTION_BAT_BRA_DISABLE intent by modifying existing logic.
- Removed extra parameters in some intents that are not required.

CRs-Fixed: 2475578
Change-Id: Ifc570915a2e0ea4c63499d27f4ddc542f60898d7
diff --git a/BATestApp/Android.mk b/BATestApp/Android.mk
index ba23089..df6c8b2 100644
--- a/BATestApp/Android.mk
+++ b/BATestApp/Android.mk
@@ -3,22 +3,13 @@
 include $(CLEAR_VARS)
 
 LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/res
-LOCAL_RESOURCE_DIR += frameworks/support/v7/appcompat/res
-LOCAL_RESOURCE_DIR += frameworks/support/v7/recyclerview/res
 
 LOCAL_AAPT_FLAGS := --auto-add-overlay
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SRC_FILES += src/org/codeaurora/bluetooth/batestapp/IGattBroadcastServiceCallback.aidl
-LOCAL_SRC_FILES += src/org/codeaurora/bluetooth/batestapp/IGattBroadcastService.aidl
 
 LOCAL_AIDL_INCLUDES += system/bt/binder
 
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-v4 \
-    android-support-v7-recyclerview \
-    android-support-v7-appcompat
-
 LOCAL_PACKAGE_NAME := BATestApp
 LOCAL_PRIVILEGED_MODULE := true
 LOCAL_CERTIFICATE := platform
diff --git a/BATestApp/AndroidManifest.xml b/BATestApp/AndroidManifest.xml
index 5685cff..aeb161a 100644
--- a/BATestApp/AndroidManifest.xml
+++ b/BATestApp/AndroidManifest.xml
@@ -38,7 +38,6 @@
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
-    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
     <uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS" />
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
     <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
@@ -67,15 +66,6 @@
         <service
             android:name=".GattBroadcastService"
             android:exported="true" />
-
-        <receiver
-            android:name=".BroadcastAudioAppReceiver"
-            android:enabled="true"
-            android:exported="true">
-            <intent-filter>
-                <action android:name="android.bluetooth.adapter.action.STATE_CHANGED"/>
-            </intent-filter>
-        </receiver>
     </application>
 
 </manifest>
diff --git a/BATestApp/res/layout/layout_devices.xml b/BATestApp/res/layout/layout_devices.xml
index 557795a..8ee4351 100644
--- a/BATestApp/res/layout/layout_devices.xml
+++ b/BATestApp/res/layout/layout_devices.xml
@@ -50,7 +50,7 @@
         android:layout_alignParentBottom="true"
         android:text="@string/go_previous" />
 
-    <android.support.v7.widget.RecyclerView
+    <ListView
         android:id="@+id/id_lv_deviceslist"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
diff --git a/BATestApp/res/values/styles.xml b/BATestApp/res/values/styles.xml
index ae8c7d2..00ada2e 100644
--- a/BATestApp/res/values/styles.xml
+++ b/BATestApp/res/values/styles.xml
@@ -31,14 +31,10 @@
 
 <resources>
 
-    <!-- Base application theme. -->
-    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
-        <!-- Customize your theme here. -->
-        <item name="colorPrimary">@color/colorPrimary</item>
-        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
-        <item name="colorAccent">@color/colorAccent</item>
+    <style name="AppTheme" parent="android:Theme.Holo.Light">
+        <item name="android:windowNoTitle">true</item>
     </style>
-
+    <!-- Base application theme. -->
     <style name="style_view_app">
         <item name="android:textColor">@android:color/black</item>
         <item name="android:layout_width">match_parent</item>
@@ -47,8 +43,4 @@
         <item name="android:fontFamily">sans-serif-condensed</item>
     </style>
 
-    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
-
-    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
-
 </resources>
diff --git a/BATestApp/src/org/codeaurora/bluetooth/batestapp/AdapterDevice.java b/BATestApp/src/org/codeaurora/bluetooth/batestapp/AdapterDevice.java
index deaa64c..99641e1 100644
--- a/BATestApp/src/org/codeaurora/bluetooth/batestapp/AdapterDevice.java
+++ b/BATestApp/src/org/codeaurora/bluetooth/batestapp/AdapterDevice.java
@@ -29,31 +29,25 @@
 
 package org.codeaurora.bluetooth.batestapp;
 
-import android.bluetooth.BluetoothDevice;
-import android.support.v7.widget.RecyclerView;
+import java.util.ArrayList;
+import java.util.List;
+
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.LinearLayout;
+import android.widget.BaseAdapter;
 import android.widget.TextView;
 
-import java.util.ArrayList;
-import java.util.List;
-
-public class AdapterDevice extends RecyclerView.Adapter<AdapterDevice.ViewHolder> {
+public class AdapterDevice extends BaseAdapter {
 
     private List<BroadcastAudioDevice> mList;
     private LayoutInflater mInflater;
-    private RecyclerViewListener mListener;
-    private static final String TAG=Utils.TAG +"AdapterDevice";
+    private static final String TAG=BAAudio.TAG +" AdapterDevice";
 
-    public AdapterDevice(List<BroadcastAudioDevice> list, LayoutInflater inflater,
-            RecyclerViewListener listener) {
+    public AdapterDevice(List<BroadcastAudioDevice> list, LayoutInflater inflater) {
         mList = list;
         mInflater = inflater;
-        mListener = listener;
-        Log.v(TAG," AdapterDevice ");
     }
 
     public void refreshDevices(List<BroadcastAudioDevice> list) {
@@ -62,53 +56,49 @@
         } else {
             mList = list;
         }
-        Log.v(TAG," refreshDevices mList :"+mList.size());
+        Log.i(TAG," refreshDevices mList :"+mList.size());
         notifyDataSetChanged();
     }
 
     @Override
-    public void onBindViewHolder(ViewHolder holder, final int position) {
-
-        BroadcastAudioDevice device = mList.get(position);
-        if (device != null && device.getName() != null){
-            holder.textViewName.setText(device.getName());
-        }
-
-        if (device != null && device.getBluetoothDevice() != null){
-            holder.textViewAddress.setText(device.getBluetoothDevice()
-                                                 .getAddress());
-        }
-        holder.mLayout.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                Log.v(TAG," onClick position  :" + position);
-                mListener.onRecylerViewItemClicked(position);
-            }
-        });
-    }
-
-    @Override
-    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-        View view = mInflater.inflate(R.layout.layout_row_device, parent, false);
-        return new ViewHolder(view);
-    }
-
-    @Override
-    public int getItemCount() {
+    public int getCount() {
         return mList.size();
     }
 
-    static class ViewHolder extends RecyclerView.ViewHolder {
-
-        private TextView textViewName, textViewAddress;
-        private LinearLayout mLayout;
-
-        public ViewHolder(View v) {
-            super(v);
-            textViewName = (TextView) v.findViewById(R.id.id_tv_devicename);
-            textViewAddress = (TextView) v.findViewById(R.id.id_tv_devieaddress);
-            mLayout = (LinearLayout) v.findViewById(R.id.id_linearlayout_row);
-        }
+    @Override
+    public BroadcastAudioDevice getItem(int arg0) {
+        return mList.get(arg0);
     }
-}
 
+    @Override
+    public long getItemId(int arg0) {
+        return arg0;
+    }
+
+    @Override
+    public View getView(int arg0, View view, ViewGroup arg2) {
+        ViewHolder holder;
+        if(view == null) {
+            view = mInflater.inflate(R.layout.layout_row_device, null);
+            holder = new ViewHolder();
+            holder.textViewName = (TextView) view.findViewById(R.id.id_tv_devicename);
+            holder.textViewAddress = (TextView) view.findViewById(R.id.id_tv_devieaddress);
+            view.setTag(holder);
+        } else {
+            holder = (ViewHolder) view.getTag();
+        }
+        BroadcastAudioDevice device = getItem(arg0);
+        if (device.getName() != null){
+            holder.textViewName.setText(device.getName());
+        }
+        if (device.getBluetoothDevice() != null){
+            holder.textViewAddress.setText(device.getBluetoothDevice()
+                    .getAddress());
+        }
+        return view;
+    }
+
+    static class ViewHolder {
+        private TextView textViewName, textViewAddress;
+    }
+}
\ No newline at end of file
diff --git a/BATestApp/src/org/codeaurora/bluetooth/batestapp/BAAudio.java b/BATestApp/src/org/codeaurora/bluetooth/batestapp/BAAudio.java
index 3ea2f5f..eab8b63 100644
--- a/BATestApp/src/org/codeaurora/bluetooth/batestapp/BAAudio.java
+++ b/BATestApp/src/org/codeaurora/bluetooth/batestapp/BAAudio.java
@@ -29,51 +29,36 @@
 
 package org.codeaurora.bluetooth.batestapp;
 
-import android.app.Service;
-import android.media.AudioFocusRequest;
-import android.media.AudioAttributes;
 import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothBATransmitter;
-import android.bluetooth.BluetoothBAEncryptionKey;
-import android.bluetooth.BluetoothBAStreamServiceRecord;
+import android.bluetooth.BluetoothProfile;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.bluetooth.BluetoothProfile;
-import android.util.Log;
-import android.os.IBinder;
-import android.content.Context;
-import java.util.Map;
-import java.util.HashMap;
-
+import android.media.AudioAttributes;
+import android.media.AudioFocusRequest;
 import android.media.AudioFormat;
 import android.media.AudioManager;
-import android.media.AudioTrack;
+import android.media.AudioManager.OnAudioFocusChangeListener;
 import android.media.AudioRecord;
+import android.media.AudioTrack;
+import android.media.MediaRecorder;
+import android.media.audiofx.AcousticEchoCanceler;
+import android.media.audiofx.AutomaticGainControl;
+import android.media.audiofx.NoiseSuppressor;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
+import android.util.Log;
 
-import java.io.IOException;
-
-import android.media.MediaRecorder;
-import android.media.AudioManager;
-import android.media.AudioManager.OnAudioFocusChangeListener;
-
-import android.media.audiofx.AcousticEchoCanceler;
-import android.media.audiofx.AutomaticGainControl;
-import android.media.audiofx.NoiseSuppressor;
-
-// class to handle all interactions with Audio part of Broadcast Audio Transmitter.
+// Class to handle all interactions with Audio part of Broadcast Audio Transmitter.
 public class BAAudio {
 
+    static final String TAG = "BAAPP   ";
     public static final String BASERVICE_STATE_CHANGED = "android.bluetooth.bat.service";
     public static final String EXTRA_BA_STATE = "android.bluetooth.extra.ba.state";
     public static final String EXTRA_CONN_STATE = "android.bluetooth.extra.conn.state";
-    private static final String TAG = Utils.TAG + "BAAudio";
     private static final int SAMPLE_RATE = 16000;
     /* CHANNEL_CONFIGURATION_MONO @deprecated Use {@link #CHANNEL_OUT_MONO} or {@link #CHANNEL_IN_MONO} instead.  */
     private static final int CHANNEL_CONFIG_RECORD = AudioFormat.CHANNEL_IN_MONO;
@@ -86,17 +71,12 @@
     private final static int MSG_STOP_RECORD_PLAY = 1;
     private final static int MSG_START_RECORD_PLAY = 2;
     private final static int MSG_AUDIO_FOCUS_CHANGE = 3;
-    private static BluetoothBATransmitter sBATprofile = null;
     private static boolean sIsBAReady = false;
-    private static BluetoothBAStreamServiceRecord mServiceRecord;
     private static boolean sIsPlaying = false;
     private BluetoothAdapter mAdapter;
     private BAAudioReceiver mReceiver;
     private Context mContext;
     private int mCurrBATState;
-    private BluetoothBAEncryptionKey mCurrEncKey;
-    private int mCurrDiv;
-    private int mCurrStreamId;
     private AudioRecord mAudioRecord = null;
     private AudioTrack mAudioTrack = null;
     private int mCurrAudioFocusState = AudioManager.AUDIOFOCUS_LOSS;
@@ -105,6 +85,9 @@
     private StreamingThread mStrThread;
     // This is returned when requesting focus from AudioManager
     private AudioFocusRequest mfocusRequest;
+    private int BAT_State = BroadcastAudioAppActivity.STATE_DISABLED;
+    static int BA_TRANSMITTER = 23;
+
     private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() {
         public void onAudioFocusChange(int focusVal) {
             Log.d(TAG, "focusChangs val = " + focusVal);
@@ -114,39 +97,34 @@
     };
 
     public BAAudio(Context context) {
+
         Log.d(TAG, " BAAudio constructor");
         mContext = context;
         mReceiver = new BAAudioReceiver();
         mAdapter = BluetoothAdapter.getDefaultAdapter();
-        IntentFilter filter = new IntentFilter(BluetoothBATransmitter.ACTION_BAT_STATE_CHANGED);
-        filter.addAction(BluetoothBATransmitter.ACTION_BAT_ENCRYPTION_KEY_CHANGED);
-        filter.addAction(BluetoothBATransmitter.ACTION_BAT_DIV_CHANGED);
-        filter.addAction(BluetoothBATransmitter.ACTION_BAT_STREAMING_ID_CHANGED);
-        mContext.registerReceiver(mReceiver, filter);
-        if (mAdapter != null) {
-            mAdapter.getProfileProxy(mContext, new BATServiceListener(),
-                    BluetoothProfile.BA_TRANSMITTER);
-        }
-        mCurrEncKey = null;
-        mServiceRecord = null;
-        mCurrDiv = BluetoothBATransmitter.INVALID_DIV;
-        mCurrStreamId = 0;
-        mCurrBATState = BluetoothBATransmitter.STATE_DISABLED;
 
+        IntentFilter filter = new IntentFilter(
+                BroadcastAudioAppActivity.ACTION_BAT_STATE_CHANGED);
+        filter.addAction(BroadcastAudioAppActivity.ACTION_BAT_ENCRYPTION_KEY_CHANGED);
+        filter.addAction(BroadcastAudioAppActivity.ACTION_BAT_STATE_CHANGED);
+        mContext.registerReceiver(mReceiver, filter);
+
+        mCurrBATState = BroadcastAudioAppActivity.STATE_DISABLED;
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+
         HandlerThread thread = new HandlerThread("BAaudioHandler");
         thread.start();
         Looper looper = thread.getLooper();
         mHandler = new BAMsgHandler(looper);
-        AudioAttributes streamAttributes =
-             new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA)
-                                          .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
-                                          .build();
-        mfocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
-                                      .setAudioAttributes(streamAttributes)
-                                      .setOnAudioFocusChangeListener(mAudioFocusListener)
-                                      .build();
 
+        AudioAttributes streamAttributes =
+                new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA)
+                        .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+                                .build();
+        mfocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
+                .setAudioAttributes(streamAttributes)
+                        .setOnAudioFocusChangeListener(mAudioFocusListener)
+                                .build();
     }
 
     public void broadcastServiceConnection(boolean isConnected, int state) {
@@ -167,107 +145,13 @@
             mContext.unregisterReceiver(mReceiver);
         }
     }
-
-    public boolean enableBA() {
-        Log.d(TAG, " enableBA currState = " + mCurrBATState);
-        if (sBATprofile == null) {
-            Log.d(TAG, " profile null, return");
-            return false;
-        }
-        if ((mCurrBATState == BluetoothBATransmitter.STATE_PAUSED) ||
-                (mCurrBATState == BluetoothBATransmitter.STATE_PLAYING)) {
-            return false;
-        }
-        return sBATprofile.setBATState(BluetoothBATransmitter.ENABLE_BA_TRANSMITTER);
-    }
-
-    public boolean disableBA() {
-        Log.d(TAG, " disableBA currState = " + mCurrBATState);
-        if (sBATprofile == null) {
-            Log.d(TAG, " profile null, return");
-            return false;
-        }
-        if (mCurrBATState == BluetoothBATransmitter.STATE_DISABLED) {
-            return false;
-        }
-        return sBATprofile.setBATState(BluetoothBATransmitter.DISABLE_BA_TRANSMITTER);
-    }
-
-    public int getBATState() {
-        Log.d(TAG, " getBATState currState = " + mCurrBATState);
-        if (sBATprofile != null) {
-            mCurrBATState = sBATprofile.getBATState();
-        }
-        Log.d(TAG, " getBATState returning  = " + mCurrBATState);
-        return mCurrBATState;
-    }
-
-    public BluetoothBAEncryptionKey getEncKey() {
-        Log.d(TAG, " getEncKey currState = " + mCurrBATState);
-        if (sBATprofile != null) {
-            mCurrEncKey = sBATprofile.getEncryptionKey();
-        }
-        for (int i = 0; i < BluetoothBAEncryptionKey.ENCRYPTION_KEY_LENGTH; i++) {
-            if (mCurrEncKey != null)
-                Log.d(TAG, " EncrycptionKey[ " + i + "] = " + mCurrEncKey.getEncryptionKey()[i]);
-        }
-        return mCurrEncKey;
-    }
-
-    public int getStreamId() {
-        Log.d(TAG, " getStreamId mCurrStreamId = " + mCurrStreamId);
-        if (sBATprofile != null) {
-            mCurrStreamId = (int) sBATprofile.getStreamId();
-        }
-        Log.d(TAG, " getStreamid returning  = " + mCurrStreamId);
-        return mCurrStreamId;
-    }
-
-    public int getDIV() {
-        Log.d(TAG, " getDIV mCurrDiv = " + mCurrDiv);
-        if (sBATprofile != null) {
-            mCurrDiv = sBATprofile.getDIV();
-        }
-        Log.d(TAG, " getDIV returning  = " + mCurrDiv);
-        return mCurrDiv;
-    }
-
-    public boolean refreshEncryptionKey() {
-        Log.d(TAG, " refreshEncryptionKey mCurrBATState = " + mCurrBATState);
-        if (sBATprofile == null) {
-            return false;
-        }
-        return sBATprofile.refreshEncryptionKey();
-    }
-
-    public BluetoothBAStreamServiceRecord getBAServiceRecord() {
-        Log.d(TAG, " getBAServiceRecord mCurrBATState = " + mCurrBATState);
-        if (sBATprofile == null) {
-            Log.d(TAG, " Profile not up, return null ");
-            return null;
-        }
-        try {
-            mServiceRecord = sBATprofile.getBAServiceRecord();
-            Long[] streamIDs = mServiceRecord.getStreamIds();
-            Log.d(TAG, " streamIDs =  " + streamIDs.length + "streamId = " + streamIDs[0]);
-            Map<Integer, Long> mServiceRecordData = mServiceRecord.getServiceRecord(streamIDs[0]);
-            for (Map.Entry<Integer, Long> entry : mServiceRecordData.entrySet()) {
-                Log.d(TAG, " Key< " + entry.getKey() + " >" + " value <" + entry.getValue() + ">");
-            }
-        } catch (Exception e) {
-            Log.d(TAG, " Exception occured ");
-            return null;
-        }
-        return mServiceRecord;
-    }
-
     private synchronized void initAudioRecordSink() {
-        mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_RATE,
-                CHANNEL_CONFIG_RECORD, AUDIO_FORMAT, RECORD_BUF_SIZE);
+        mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION,
+                SAMPLE_RATE, CHANNEL_CONFIG_RECORD, AUDIO_FORMAT, RECORD_BUF_SIZE);
         Log.d(TAG," mAudioRecord initialized = " + mAudioRecord.getState());
         if (AutomaticGainControl.isAvailable()) {
-            AutomaticGainControl agc = AutomaticGainControl.create(mAudioRecord.getAudioSessionId
-                    ());
+            AutomaticGainControl agc = AutomaticGainControl.create(
+                    mAudioRecord.getAudioSessionId());
             if (agc != null) {
                 Log.d(TAG, "AGC is " + (agc.getEnabled() ? "enabled" : "disabled"));
                 agc.setEnabled(true);
@@ -296,8 +180,8 @@
             if (aec != null) {
                 Log.d(TAG, "AEC is " + (aec.getEnabled() ? "enabled" : "disabled"));
                 aec.setEnabled(true);
-                Log.d(TAG, "AEC is " + (aec.getEnabled() ? "enabled" : "disabled" + " after trying to" +
-                        " disable"));
+                Log.d(TAG, "AEC is " + (aec.getEnabled() ? "enabled" : "disabled"
+                        + " after trying to" + " disable"));
             }
         } else {
             Log.d(TAG, "aec is unavailable");
@@ -341,34 +225,18 @@
         }
     }
 
-    class BATServiceListener implements BluetoothProfile.ServiceListener {
-        @Override
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            Log.d(TAG, " onServiceConnected profile = " + profile);
-            sBATprofile = (BluetoothBATransmitter) proxy;
-            sIsBAReady = true;
-            mCurrBATState = sBATprofile.getBATState();
-            broadcastServiceConnection(true, mCurrBATState);
-        }
-
-        @Override
-        public void onServiceDisconnected(int profile) {
-            Log.d(TAG, " onServiceDisconnected profile = " + profile);
-            sIsBAReady = false;
-            mCurrBATState = BluetoothBATransmitter.STATE_DISABLED;
-            sBATprofile = null;
-            broadcastServiceConnection(false, mCurrBATState);
-        }
-    }
-
     private class BAAudioReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
+
             String action = intent.getAction();
-            int extraVal = 0;
             Log.d(TAG, action);
-            if (action.equals(BluetoothBATransmitter.ACTION_BAT_STATE_CHANGED)) {
-                extraVal = intent.getIntExtra(BluetoothBATransmitter.EXTRA_STATE,
+            int extraVal = 0;
+
+            if(action == null)
+                return;
+            if (action.equals(BroadcastAudioAppActivity.ACTION_BAT_STATE_CHANGED)) {
+                extraVal = intent.getIntExtra(BroadcastAudioAppActivity.EXTRA_STATE,
                         -1);
                 if (extraVal != -1)
                     mCurrBATState = extraVal;
@@ -376,26 +244,10 @@
                         "extraVal = "
                         + extraVal);
             }
-            if (action.equals(BluetoothBATransmitter.ACTION_BAT_ENCRYPTION_KEY_CHANGED)) {
-                mCurrEncKey = (BluetoothBAEncryptionKey) intent.getParcelableExtra
-                        (BluetoothBATransmitter.EXTRA_ECNRYPTION_KEY);
-                Log.d(TAG, " ACTION_BAT_ENCRYPTION_KEY_CHANGED ");
-            }
-            if (action.equals(BluetoothBATransmitter.ACTION_BAT_DIV_CHANGED)) {
-                extraVal = intent.getIntExtra(BluetoothBATransmitter.EXTRA_DIV_VALUE,
-                        -1);
-                if (extraVal != -1)
-                    mCurrDiv = extraVal;
-                Log.d(TAG, " ACTION_BAT_DIV_CHANGED mCurrDiv = " + mCurrDiv + "extraVal = " +
-                        extraVal);
-            }
-            if (action.equals(BluetoothBATransmitter.ACTION_BAT_STREAMING_ID_CHANGED)) {
-                extraVal = intent.getIntExtra(BluetoothBATransmitter.EXTRA_STREAM_ID,
-                        -1);
-                if (extraVal != -1)
-                    mCurrStreamId = extraVal;
-                Log.d(TAG, " ACTION_BAT_STREAMING_ID_CHANGED mCurrStreamId = "
-                        + mCurrStreamId + " extraVal = " + extraVal);
+            // Need to get BAT State for above class.
+            if (action.equals(BroadcastAudioAppActivity.ACTION_BAT_STATE_CHANGED)) {
+                final int state = intent.getIntExtra(BroadcastAudioAppActivity.EXTRA_STATE, -1);
+                BAT_State = state;
             }
         }
     }
@@ -445,9 +297,9 @@
                 case MSG_START_RECORD_PLAY:
                     Log.d(TAG, " Current Audio Focus = " + mCurrAudioFocusState);
                     if (mCurrAudioFocusState == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT)
-                        Log.d(TAG, " Transient Loss occused, call must be in progress, don't " +
-                                "start now ");
-                    //requestAudioFocus (AudioManager.OnAudioFocusChangeListener l, int, int)
+                        Log.d(TAG, " Transient Loss occurred, call must be in progress, don't "
+                            + "start now ");
+                    // requestAudioFocus (AudioManager.OnAudioFocusChangeListener l, int, int)
                     // method was deprecated in API level 26. use requestAudioFocus(AudioFocusRequest)
                     int focusGranted = mAudioManager.requestAudioFocus(mfocusRequest);
                     Log.d(TAG, " Focus Granted = " + focusGranted);
@@ -516,4 +368,4 @@
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/BATestApp/src/org/codeaurora/bluetooth/batestapp/BroadcastAudioAppActivity.java b/BATestApp/src/org/codeaurora/bluetooth/batestapp/BroadcastAudioAppActivity.java
index 48cd457..7c9ae4c 100644
--- a/BATestApp/src/org/codeaurora/bluetooth/batestapp/BroadcastAudioAppActivity.java
+++ b/BATestApp/src/org/codeaurora/bluetooth/batestapp/BroadcastAudioAppActivity.java
@@ -29,79 +29,128 @@
 
 package org.codeaurora.bluetooth.batestapp;
 
-import android.Manifest;
+import android.app.Activity;
 import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.PackageManager;
+import android.os.Handler;
+import android.os.Message;
 import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.ActivityCompat;
 import android.util.Log;
-
 import android.view.View;
 import android.widget.Button;
 import android.widget.CompoundButton;
 import android.widget.ToggleButton;
-import android.app.Activity;
-import org.codeaurora.bluetooth.batestapp.BAAudio;
-import android.bluetooth.BluetoothBATransmitter;
-
+import android.widget.Toast;
 
 public class BroadcastAudioAppActivity extends Activity implements
-        CompoundButton.OnCheckedChangeListener, View.OnClickListener {
+    CompoundButton.OnCheckedChangeListener, View.OnClickListener {
 
-    //private ToggleButton mBtnBtEnable;
-    private ToggleButton mBAEnable;
-    private ToggleButton mMegaPhoneEnable;
+    public static final String ACTION_BAT_BA_ENABLE =
+            "com.android.bluetooth.bat.profile.action.BA_ENABLE";
+    public static final String ACTION_BAT_BA_DISABLE =
+            "com.android.bluetooth.bat.profile.action.BA_DISABLE";
+    public static final String ACTION_BAT_BRA_ENABLE =
+            "com.android.bluetooth.bat.profile.action.BRA_ENABLE";
+    public static final String ACTION_BAT_BRA_DISABLE =
+            "com.android.bluetooth.bat.profile.action.BRA_DISABLE";
+    public static final String ACTION_BAT_ENCRYPTION_KEY_REFRESH =
+            "com.android.bluetooth.bat.profile.action.ENCRYPTION_KEY_REFRESH";
+    public static final String ACTION_BAT_ASSOCIATE_BCA_RECEIVER =
+            "com.android.bluetooth.bat.profile.action.ASSOCIATE_BCA_RECEIVER";
+    public static final String ACTION_BAT_STATE_CHANGED =
+            "com.android.bluetooth.bat.profile.action.BA_STATE_CHANGED";
+    public static final String EXTRA_STATE =
+            "com.android.bluetooth.bat.profile.extra.STATE";
+    public static final String EXTRA_PREVIOUS_STATE =
+            "com.android.bluetooth.bat.profile.extra.PREV_STATE";
+    public static final String ACTION_BAT_ONFOUND_ONLOST_BCA_RECEIVER =
+            "com.android.bluetooth.bat.profile.action.ONFOUND_ONLOST_BCA_RECEIVER";
+    public static final String EXTRA_SCAN_RESULT =
+            "com.android.bluetooth.bat.profile.extra.EXTRA_SCAN_RESULT";
+    public static final String EXTRA_ONFOUND =
+            "com.android.bluetooth.bat.profile.extra.EXTRA_ONFOUND";
+    public static final String ACTION_BAT_BRA_STATE_CHANGED =
+            "com.android.bluetooth.bat.profile.action.BRA_STATE_CHANGED";
+    public static final String EXTRA_STATUS =
+            "com.android.bluetooth.bat.profile.extra.STATUS";
+    public static final String ACTION_BAT_ON_ASSOCIATED_BCA_RECEIVER =
+            "com.android.bluetooth.bat.profile.action.ON_ASSOCIATED_BCA_RECEIVER";
+    public static final String ACTION_BAT_ENCRYPTION_KEY_CHANGED =
+            "com.android.bluetooth.bat.profile.action.BA_ENC_KEY_CHANGED";
+    public static final String EXTRA_ECNRYPTION_KEY =
+            "com.android.bluetooth.bat.profile.extra.ENC_KEY";
+
+    public static final int STATE_DISABLED = 0;
+    public static final int STATE_PAUSED = 1;
+    public static final int STATE_PLAYING = 2;
+
+    private static final String TAG = BAAudio.TAG + "BAAppActivity";
+    BAAudio mBAAudiobj = null;
+    private ToggleButton mBAEnable, mMegaPhoneEnable;
     private BluetoothAdapter mBtAdapter;
-    private String mMsg;
-    private static final String TAG = Utils.TAG +"BroadcastAudioAppActivity";
-    private final int REQUEST_ENABLE_BT = 1001;
-    private final int PERMISSIONS_REQUEST_BLUETOOTH = 1002;
-    private Button mBtnBRAEnable;
-    private Button mBtnChangeEnc;
-    BAAudio mBAAudiobj =  null;
+    private Button mBtnBRAEnable, mBtnChangeEnc;
     private boolean isStateChangePending = false;
-    private int expectedState = BluetoothBATransmitter.STATE_DISABLED;
+    private int expectedState = STATE_DISABLED;
+    private int BATState = STATE_DISABLED;
+
+    // Implementation of 30 sec Timeout for BT
+    private static final int BA_ENABLE_TIMEOUT = 0;
+    private static final int BA_ENABLE_TIMEOUT_VALUE = 30000;
+
+    private void onTimeout() {
+        mTimeoutHandler.sendMessageDelayed(mTimeoutHandler.obtainMessage(BA_ENABLE_TIMEOUT),
+                BA_ENABLE_TIMEOUT_VALUE);
+    }
+
+    private final Handler mTimeoutHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case BA_ENABLE_TIMEOUT:
+                    Context context = getApplicationContext();
+                    Toast toast = Toast.makeText(context, "BA Not enabled properly", Toast.LENGTH_SHORT);
+                    toast.show();
+                    Log.d(TAG, "BA not enabled properly");
+                    isStateChangePending = false;
+                    break;
+                default:
+                    break;
+            }
+        }
+    };
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         Log.d(TAG, "onCreate ");
         super.onCreate(savedInstanceState);
+
         setContentView(R.layout.layout_main);
         mBAEnable = (ToggleButton) findViewById(R.id.id_switch_bt_enable);
         mBAEnable.setOnCheckedChangeListener(this);
-        mMegaPhoneEnable =  (ToggleButton) findViewById(R.id.id_switch_mp);
+        mMegaPhoneEnable = (ToggleButton) findViewById(R.id.id_switch_mp);
         mMegaPhoneEnable.setOnCheckedChangeListener(this);
         mBtnChangeEnc = (Button) findViewById(R.id.id_btn_enc_change);
         mBtnChangeEnc.setOnClickListener(this);
-
         mBtnBRAEnable = (Button) findViewById(R.id.id_btn_enable_bra);
         mBtnBRAEnable.setOnClickListener(this);
         mBtnBRAEnable.setEnabled(false);
-
         mBtAdapter = BluetoothAdapter.getDefaultAdapter();
+
         if (mBtAdapter == null) {
             Log.d(TAG, " Device does not support Bluetooth");
             return;
         }
-
         boolean isBtEnabled = mBtAdapter.isEnabled();
-        if (isBtEnabled) {
-            startService(new Intent(BroadcastAudioAppActivity.this, GattBroadcastService.class));
-        }
 
         IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
-        filter.addAction(BluetoothBATransmitter.ACTION_BAT_STATE_CHANGED);
+        filter.addAction(ACTION_BAT_STATE_CHANGED);
         filter.addAction(BAAudio.BASERVICE_STATE_CHANGED);
         registerReceiver(mReceiver, filter);
 
-        Log.d(TAG, " Creating BAAudio ");
         mBAAudiobj = new BAAudio(getApplicationContext());
-        Log.d(TAG, " LauncherActivity  constructor - ");
     }
 
     @Override
@@ -116,51 +165,53 @@
 
     @Override
     public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
-        Log.d(TAG, " onCheckChanged isChecked = " + isChecked + " button = " + compoundButton
-                                                 +" stateChangePending " + isStateChangePending);
-            if(mBtAdapter == null) return;
-            if (!mBtAdapter.isEnabled()) return;
-            if (mBAAudiobj == null) return;
 
-            if (compoundButton == mBAEnable) {
-                if (isStateChangePending) return;
-                if (isChecked) {
-                    if(mBAAudiobj.getBATState() == BluetoothBATransmitter.STATE_DISABLED) {
-                        isStateChangePending = true;
-                        expectedState = BluetoothBATransmitter.STATE_PAUSED;
-                        mBAEnable.setEnabled(false);
-                        mBAAudiobj.enableBA();
-                    }
-                } else {
-                   if(mBAAudiobj.getBATState() != BluetoothBATransmitter.STATE_DISABLED) {
-                       isStateChangePending = true;
-                       expectedState = BluetoothBATransmitter.STATE_DISABLED;
-                       mBAEnable.setEnabled(false);
-                       mBAAudiobj.disableBA();
-                   }
+        Log.d(TAG, " onCheckChanged isChecked = " + isChecked + " button = " +
+                compoundButton + " stateChangePending " + isStateChangePending);
+
+        if (mBtAdapter == null || !mBtAdapter.isEnabled() || mBAAudiobj == null)
+            return;
+
+        if (compoundButton == mBAEnable) {
+            if (isStateChangePending)
+                return;
+            if (isChecked) {
+                if(BATState == STATE_DISABLED) {
+                    isStateChangePending = true;
+                    expectedState = STATE_PAUSED;
+                    mBAEnable.setEnabled(false);
+                    Intent intent_to_enable_BA = new Intent(ACTION_BAT_BA_ENABLE);
+                    sendBroadcast(intent_to_enable_BA);
+                    onTimeout();
                 }
+            } else {
+               if(BATState != STATE_DISABLED) {
+                   isStateChangePending = true;
+                   expectedState = STATE_DISABLED;
+                   mBAEnable.setEnabled(false);
+                   Intent intent_to_disable_BA = new Intent(ACTION_BAT_BA_DISABLE);
+                   sendBroadcast(intent_to_disable_BA);
+               }
             }
-            if (compoundButton == mMegaPhoneEnable) {
-                if (isChecked) {
-                    boolean started = mBAAudiobj.startRecordAndPlay();
-                    setMPButtonText(started);
-                } else {
-                   mBAAudiobj.stopRecordAndPlay();
-                   setMPButtonText(false);
-                }
+        } else if (compoundButton == mMegaPhoneEnable) {
+            if (isChecked) {
+                boolean started = mBAAudiobj.startRecordAndPlay();
+                setMPButtonText(started);
+            } else {
+               mBAAudiobj.stopRecordAndPlay();
+               setMPButtonText(false);
             }
+        }
     }
 
     @Override
     public void onClick(View view) {
-        Log.d(TAG, " onClick  view :"+view);
         if (view == mBtnBRAEnable) {
             startActivity(new Intent(BroadcastAudioAppActivity.this,
                     BroadcastAudioDeviceListActivity.class));
-        }
-        if (view == mBtnChangeEnc) {
-            if (mBAAudiobj == null) return;
-            mBAAudiobj.refreshEncryptionKey();
+        } else if (view == mBtnChangeEnc) {
+            Intent intent_to_refresh_EncKey = new Intent(ACTION_BAT_ENCRYPTION_KEY_REFRESH);
+            sendBroadcast(intent_to_refresh_EncKey);
         }
     }
 
@@ -173,22 +224,20 @@
             if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter
                         .ERROR);
-                int prevState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE,
-                        BluetoothAdapter.ERROR);
-                //setButtonText(state);
                 if (state == BluetoothAdapter.STATE_TURNING_OFF
                     || state == BluetoothAdapter.STATE_OFF) {
-                    setBRAButtonState(BluetoothBATransmitter.STATE_DISABLED);
+                    setBRAButtonState(STATE_DISABLED);
                 }
             }
 
-            if (action.equals(BluetoothBATransmitter.ACTION_BAT_STATE_CHANGED)) {
-                final int state = intent.getIntExtra(BluetoothBATransmitter.EXTRA_STATE,
-                        -1);
+            if (action.equals(ACTION_BAT_STATE_CHANGED)) {
+                final int state = intent.getIntExtra(EXTRA_STATE, -1);
+                BATState = state;
                 if(state != -1) {
                     setBRAButtonState(state);
+                    mTimeoutHandler.removeCallbacksAndMessages(null);
                     Log.d(TAG, " stateChangePending " + isStateChangePending + " expectedState = "
-                            +expectedState + " state " + state);
+                            + expectedState + " state " + state);
                     if (isStateChangePending) {
                         isStateChangePending = false;
                         mBAEnable.setEnabled(true);
@@ -202,9 +251,10 @@
                 }
             }
             if (action.equals(BAAudio.BASERVICE_STATE_CHANGED)) {
-                final boolean serviceState = intent.getBooleanExtra(BAAudio.EXTRA_CONN_STATE, false);
+                final boolean serviceState = intent.getBooleanExtra(BAAudio.EXTRA_CONN_STATE,
+                        false);
                 final int baState = intent.getIntExtra(BAAudio.EXTRA_BA_STATE, -1);
-                Log.d(TAG, " Service state changed servicState = "
+                Log.d(TAG, " Service state changed serviceState = "
                         + serviceState + " baState = " + baState);
                 setBAButtonText(baState);
             }
@@ -223,14 +273,13 @@
     private void setBAButtonText(int state) {
         boolean currentCheckStatus = mBAEnable.isChecked();
         Log.d(TAG," setBAButtonText state = " + state + " isChecked() = " + currentCheckStatus);
-        if(state == BluetoothBATransmitter.STATE_DISABLED) {
+        if(state == STATE_DISABLED) {
             if (currentCheckStatus) {
-                // button was cheked and we are making it false, need to set it
+                // button was checked and we are making it false, need to set it
                 Log.d(TAG, " setting button false ");
                 mBAEnable.setChecked(false);
             }
-        }
-        else {
+        } else {
             if (!currentCheckStatus) {
                Log.d(TAG, " setting button true ");
                mBAEnable.setChecked(true);
@@ -240,10 +289,10 @@
 
     private void setBRAButtonState(int state) {
         Log.d(TAG, "setBRAButtonState state : "+state);
-        if(state == BluetoothBATransmitter.STATE_DISABLED) {
+        if(state == STATE_DISABLED) {
             mBtnBRAEnable.setEnabled(false);
         } else {
             mBtnBRAEnable.setEnabled(true);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/BATestApp/src/org/codeaurora/bluetooth/batestapp/BroadcastAudioAppReceiver.java b/BATestApp/src/org/codeaurora/bluetooth/batestapp/BroadcastAudioAppReceiver.java
deleted file mode 100644
index aaa1a47..0000000
--- a/BATestApp/src/org/codeaurora/bluetooth/batestapp/BroadcastAudioAppReceiver.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials provided
- *      with the distribution.
- *    * Neither the name of The Linux Foundation nor the names of its
- *      contributors may be used to endorse or promote products derived
- *      from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codeaurora.bluetooth.batestapp;
-
-import android.util.Log;
-import android.content.BroadcastReceiver;
-import android.bluetooth.BluetoothAdapter;
-import android.content.Context;
-import android.content.Intent;
-
-
-public class BroadcastAudioAppReceiver extends BroadcastReceiver {
-
-    private static final String TAG = Utils.TAG +"BroadcastAudioAppReceiver";
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        String action = intent.getAction();
-        Log.d(TAG, " Action :" + action);
-
-        if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
-            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
-            int prevState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE,
-                    BluetoothAdapter.ERROR);
-            if (state == BluetoothAdapter.STATE_ON) {
-                Log.d(TAG, "state == BluetoothAdapter.STATE_ON");
-                try {
-                    context.startService(new Intent(context, GattBroadcastService.class));
-                } catch (IllegalStateException e) {
-                    Log.e(TAG, " GattBroadcastService start failed " + e.toString());
-                }
-            }
-        }
-    }
-}
diff --git a/BATestApp/src/org/codeaurora/bluetooth/batestapp/BroadcastAudioDeviceListActivity.java b/BATestApp/src/org/codeaurora/bluetooth/batestapp/BroadcastAudioDeviceListActivity.java
index 5f1eb51..e31deed 100644
--- a/BATestApp/src/org/codeaurora/bluetooth/batestapp/BroadcastAudioDeviceListActivity.java
+++ b/BATestApp/src/org/codeaurora/bluetooth/batestapp/BroadcastAudioDeviceListActivity.java
@@ -29,109 +29,118 @@
 
 package org.codeaurora.bluetooth.batestapp;
 
-import android.Manifest;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import android.app.Activity;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.le.ScanResult;
 import android.bluetooth.le.ScanRecord;
-
+import android.bluetooth.le.ScanResult;
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.ServiceConnection;
-
 import android.os.Bundle;
-import android.os.Message;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.RemoteException;
-
+import android.os.Message;
 import android.util.Log;
-import android.support.annotation.NonNull;
-import android.app.Activity;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
 import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
 import android.widget.Button;
+import android.widget.ListView;
 
-import org.codeaurora.bluetooth.batestapp.IGattBroadcastService;
-import org.codeaurora.bluetooth.batestapp.IGattBroadcastServiceCallback;
-import org.codeaurora.bluetooth.batestapp.BroadcastAudioDevice;
+public class BroadcastAudioDeviceListActivity extends Activity
+    implements View.OnClickListener, OnItemClickListener {
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.Collections;
-
-public class BroadcastAudioDeviceListActivity extends Activity implements View.OnClickListener,
-        RecyclerViewListener {
-
-    private static final String TAG = Utils.TAG + "BroadcastAudioDeviceListActivity";
+    private static final String TAG = BAAudio.TAG + " BAListActivity";
     GattBroadcastServiceClientHandler mGattBroadcastServiceClientHandler;
-    boolean mIsCountdownLatchEnabled = false;
     boolean mIsAssociationInProgress = false;
     boolean mIsBRAEnabled = false;
-    private RecyclerView mRvDevices;
-    private AdapterDevice mAdapterDevice;
     BroadcastAudioDevice mDevice;
+
+    private ListView mLvDevices;
+    private AdapterDevice mAdapterDevice;
     private List<BroadcastAudioDevice> mList;
-    private BluetoothAdapter mBtAdapter;
-    private Context mCtx;
     private Button mBtnBack;
-    private CountDownLatch mDeinitSignal = new CountDownLatch(1);
     private boolean mIsCleanupCompleted = false;
 
+    public static final int BRA_ENABLED_SUCCESS = 0;
+    public static final int BRA_ENABLED_FAILED = 1;
+    public static final int BRA_DISABLED_SUCCESS = 2;
+    public static final int BRA_DISABLED_FAILED = 3;
+    public static final int ASSOCIATE_BCA_RECEIVER_SUCCESS = 4;
+    public static final int ASSOCIATE_BCA_RECEIVER_FAILED = 5;
+    private static final int CONFIGURE_BROADCAST_RECEIVER_ASSOCIATION = 2;
+
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
 
             final String action = intent.getAction();
-            Log.d(TAG, " Action " + action);
+            Log.d(TAG, " action " + action);
+
+            if(action == null)
+                return;
             if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter
                         .ERROR);
-                int prevState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE,
-                        BluetoothAdapter.ERROR);
                 if (state == BluetoothAdapter.STATE_TURNING_OFF) {
                     cleanup();
                     finish();
                 }
+            } else if (action.equals(
+                    BroadcastAudioAppActivity.ACTION_BAT_ONFOUND_ONLOST_BCA_RECEIVER)) {
+                ScanResult result = (ScanResult) intent.getParcelableExtra(
+                        BroadcastAudioAppActivity.EXTRA_SCAN_RESULT);
+                boolean isFound = intent.getBooleanExtra(BroadcastAudioAppActivity.EXTRA_ONFOUND,
+                        false);
+                onFoundOnLostBCAReceiver(result, isFound);
+            } else if (action.equals(
+                    BroadcastAudioAppActivity.ACTION_BAT_ON_ASSOCIATED_BCA_RECEIVER)) {
+                int status = intent.getIntExtra(BroadcastAudioAppActivity.EXTRA_STATUS, -1);
+                BluetoothDevice dev = (BluetoothDevice) intent.getParcelableExtra(
+                        BluetoothDevice.EXTRA_DEVICE);
+                onAssociatedBCAReceiver(dev, status);
+            } else if (action.equals(BroadcastAudioAppActivity.ACTION_BAT_BRA_STATE_CHANGED)) {
+                int status = intent.getIntExtra(BroadcastAudioAppActivity.EXTRA_STATUS, -1);
+                onConfiguredBroadcastReceiverAssociation(status);
             }
         }
     };
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
-        Log.d(TAG, " oncreate:");
+
         super.onCreate(savedInstanceState);
         setContentView(R.layout.layout_devices);
-        mRvDevices = (RecyclerView) findViewById(R.id.id_lv_deviceslist);
-        mRvDevices.setLayoutManager(new LinearLayoutManager(this));
+
+        mLvDevices = (ListView) findViewById(R.id.id_lv_deviceslist);
         mList = Collections.synchronizedList(new ArrayList<BroadcastAudioDevice>());
-        mAdapterDevice = new AdapterDevice(mList, getLayoutInflater(), this);
-        mRvDevices.setAdapter(mAdapterDevice);
+        mAdapterDevice = new AdapterDevice(mList, getLayoutInflater());
+        mLvDevices.setAdapter(mAdapterDevice);
+        mLvDevices.setOnItemClickListener(this);
         mBtnBack = (Button) findViewById(R.id.id_btn_back);
         mBtnBack.setOnClickListener(this);
         mBtnBack.setEnabled(true);
-        mCtx = getApplicationContext();
-        mBtAdapter = BluetoothAdapter.getDefaultAdapter();
+
         IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
+        filter.addAction(BroadcastAudioAppActivity.ACTION_BAT_BRA_STATE_CHANGED);
+        filter.addAction(BroadcastAudioAppActivity.ACTION_BAT_ONFOUND_ONLOST_BCA_RECEIVER);
+        filter.addAction(BroadcastAudioAppActivity.ACTION_BAT_ON_ASSOCIATED_BCA_RECEIVER);
         registerReceiver(mReceiver, filter);
 
         HandlerThread thread = new HandlerThread("GattBroadcastServiceClientHandler");
         thread.start();
         Looper looper = thread.getLooper();
 
-        mGattBroadcastServiceClientHandler = new GattBroadcastServiceClientHandler(this, looper);
-
-
+        mGattBroadcastServiceClientHandler = new GattBroadcastServiceClientHandler(looper);
+        mGattBroadcastServiceClientHandler.sendMessage(
+                mGattBroadcastServiceClientHandler.obtainMessage(
+                        CONFIGURE_BROADCAST_RECEIVER_ASSOCIATION, true));
     }
 
     @Override
@@ -155,21 +164,9 @@
                 mBtnBack.setEnabled(false);
                 mGattBroadcastServiceClientHandler.sendMessage(
                         mGattBroadcastServiceClientHandler.obtainMessage(
-                                GattBroadcastServiceClientHandler
-                                        .CONFIGURE_BROADCAST_RECEIVER_ASSOCIATION,
+                                CONFIGURE_BROADCAST_RECEIVER_ASSOCIATION,
                                 false));
             }
-            mGattBroadcastServiceClientHandler.sendMessage(
-                    mGattBroadcastServiceClientHandler.obtainMessage(
-                            GattBroadcastServiceClientHandler.UNREGISTER_CALLBACK));
-            mIsCountdownLatchEnabled = true;
-            Log.i(TAG, "Waiting for deinit to complete");
-            try {
-                mDeinitSignal.await();
-            } catch (InterruptedException e) {
-                Log.e(TAG, "Interrupt received while waitinf for de-init to complete", e);
-            }
-
             mGattBroadcastServiceClientHandler.close();
             mGattBroadcastServiceClientHandler.removeCallbacksAndMessages(null);
             Looper looper = mGattBroadcastServiceClientHandler.getLooper();
@@ -191,19 +188,14 @@
     }
 
     @Override
-    public void onRecylerViewItemClicked(int clickedPos) {
-        Log.v(TAG, "onRecylerViewItemClicked position : " + clickedPos);
-        BroadcastAudioDevice device = mList.get(clickedPos);
+    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
+        BroadcastAudioDevice device = mList.get(arg2);
         String msg = getString(R.string.msg_association_initiated, device.getName());
-        Log.v(TAG, "onRecylerViewItemClicked device name  : " + msg);
-
         if (mIsAssociationInProgress) {
             Log.d(TAG, "Association is in progress ignore click");
             return;
         }
-
         if (mGattBroadcastServiceClientHandler != null) {
-            Utils.toast(mCtx, msg);
             Log.d(TAG, " sendMessage ASSOCIATE_BCA_RECEIVER" );
             mGattBroadcastServiceClientHandler.sendMessage(
                     mGattBroadcastServiceClientHandler.obtainMessage(
@@ -214,12 +206,10 @@
         } else {
             Log.e(TAG, "mGattBroadcastServiceClientHandler is null");
         }
-        Log.v(TAG, "onRecylerViewItemClicked position end ");
     }
 
-    private synchronized void  addOrRemoveBCAReceiverDevice(BroadcastAudioDevice device,
+    private synchronized void addOrRemoveBCAReceiverDevice(BroadcastAudioDevice device,
             boolean isAdd) {
-
         boolean isFound = false;
         BluetoothDevice bDevice = device.getBluetoothDevice();
         Log.d(TAG, " addOrRemoveBCAReceiverDevice: isAdd: " + isAdd);
@@ -234,7 +224,6 @@
                 break;
             }
         }
-
         if (isAdd && !isFound) {
             Log.d(TAG, " New Device Added :" + device.getName());
             mList.add(device);
@@ -249,101 +238,62 @@
                 mAdapterDevice.refreshDevices(mList);
             }
         });
-
     }
 
-    public class GattBroadcastServiceClientHandler extends Handler {
-        public static final int REGISTER_CALLBACK = 0;
-        public static final int UNREGISTER_CALLBACK = 1;
-        public static final int CONFIGURE_BROADCAST_RECEIVER_ASSOCIATION = 2;
+    public void onFoundOnLostBCAReceiver(ScanResult result, boolean isFound) {
+        ScanRecord record = result.getScanRecord();
+        String mac = result.getDevice().getAddress();
+        Log.d(TAG, "onFoundOnLostBCAReceiver: " + isFound + " mac :" + mac + "record :" + record);
+        BroadcastAudioDevice device = new BroadcastAudioDevice(result.getDevice(),
+                result.getScanRecord());
+        addOrRemoveBCAReceiverDevice(device, isFound);
+        refreshDevices();
+    }
+
+    public void onConfiguredBroadcastReceiverAssociation(int status) {
+        Log.d(TAG, "onConfiguredBroadcastReceiverAssociation status: " + status);
+        if (status == BRA_ENABLED_SUCCESS) {
+            mIsBRAEnabled = true;
+        } else if (status == BRA_DISABLED_SUCCESS) {
+            mIsBRAEnabled = false;
+        } else if (status == BRA_ENABLED_FAILED) {
+            finish();
+        } else if (status == BRA_DISABLED_FAILED) {
+            mIsBRAEnabled = false;
+        }
+    }
+
+    public void onAssociatedBCAReceiver(BluetoothDevice device, int status) {
+        Log.d(TAG, "onAssociatedBCAReceiver: status " + status);
+        if (mDevice == null){
+            Log.d(TAG, "onAssociatedBCAReceiver: Nothing to show on UI, mDevice is null");
+            return;
+        }
+
+        if (status == ASSOCIATE_BCA_RECEIVER_SUCCESS) {
+            String msg = getString(R.string.msg_association_success, mDevice.getName());
+            List<BroadcastAudioDevice> tempList =
+                    new ArrayList<BroadcastAudioDevice>(mList);
+            for (BroadcastAudioDevice BADev : tempList) {
+                if (device.equals(BADev.getBluetoothDevice())) {
+                    addOrRemoveBCAReceiverDevice(BADev, false);
+                }
+            }
+            refreshDevices();
+        } else if (status == ASSOCIATE_BCA_RECEIVER_FAILED) {
+            String msg = getString(R.string.msg_association_failed, mDevice.getName());
+        }
+        mIsAssociationInProgress = false;
+    }
+
+    private class GattBroadcastServiceClientHandler extends Handler {
         public static final int ASSOCIATE_BCA_RECEIVER = 3;
-        private Context mContext;
-        private IGattBroadcastService mService = null;
-
-        private final ServiceConnection mConnection = new ServiceConnection() {
-            public void onServiceConnected(ComponentName className, IBinder service) {
-                Log.d(TAG, "gatt Broadcast Proxy object connected");
-                mService = IGattBroadcastService.Stub.asInterface(Binder.allowBlocking(service));
-                mGattBroadcastServiceClientHandler.sendMessage(
-                        mGattBroadcastServiceClientHandler.obtainMessage(
-                                REGISTER_CALLBACK));
-                mGattBroadcastServiceClientHandler.sendMessage(
-                        mGattBroadcastServiceClientHandler.obtainMessage(
-                                CONFIGURE_BROADCAST_RECEIVER_ASSOCIATION, true));
-            }
-
-            public void onServiceDisconnected(ComponentName className) {
-                Log.d(TAG, "gatt Broadcast  Proxy object disconnected");
-                mIsBRAEnabled = false;
-                mIsAssociationInProgress = false;
-                mService = null;
-            }
-        };
-
-        private IGattBroadcastServiceCallback.Stub mServiceCallbacks =
-                new IGattBroadcastServiceCallback.Stub() {
-            public void onFoundOnLostBCAReceiver(ScanResult result, boolean isFound) {
-                ScanRecord record = result.getScanRecord();
-                String mac = result.getDevice().getAddress();
-
-                Log.d(TAG, "onFoundOnLostBCAReceiver: " + isFound);
-                Log.d(TAG, "onFoundOnLostBCAReceiver device address: " + mac);
-                Log.d(TAG, "onFoundOnLostBCAReceiver: scanRecord: " + record);
-
-                BroadcastAudioDevice device = new BroadcastAudioDevice(result.getDevice(),
-                        result.getScanRecord());
-
-                addOrRemoveBCAReceiverDevice(device, isFound);
-                refreshDevices();
-            }
-
-            public void onConfiguredBroadcastReceiverAssociation(int status) {
-                Log.d(TAG, "onConfiguredBroadcastReceiverAssociation status: " + status);
-                if (status == GattBroadcastService.BRA_ENABLED_SUCESSS) {
-                    mIsBRAEnabled = true;
-                } else if (status == GattBroadcastService.BRA_DISABLED_SUCESSS) {
-                    mIsBRAEnabled = false;
-                } else if (status == GattBroadcastService.BRA_ENABLED_FAILED) {
-                    finish();
-                } else if (status == GattBroadcastService.BRA_DISABLED_FAILED) {
-                    mIsBRAEnabled = false;
-                }
-            }
-
-            public void onAssociatedBCAReceiver(BluetoothDevice device, int status) {
-                Log.d(TAG, "onAssociatedBCAReceiver: status " + status);
-                if (mDevice == null){
-                    Log.d(TAG, "onAssociatedBCAReceiver: Nothing to show on UI, mDevice is null");
-                    return;
-                }
-
-                if (status == GattBroadcastService.ASSOCIATE_BCA_RECEIVER_SUCCESS) {
-                    String msg = getString(R.string.msg_association_success, mDevice.getName());
-                    Utils.toast(mCtx, msg);
-                    List<BroadcastAudioDevice> tempList =
-                            new ArrayList<BroadcastAudioDevice>(mList);
-                    for (BroadcastAudioDevice BADev : tempList) {
-                        if (device.equals(BADev.getBluetoothDevice())) {
-                            addOrRemoveBCAReceiverDevice(BADev, false);
-                        }
-                    }
-                    refreshDevices();
-                } else if (status == GattBroadcastService.ASSOCIATE_BCA_RECEIVER_FAILED) {
-                    String msg = getString(R.string.msg_association_failed, mDevice.getName());
-                    Utils.toast(mCtx, msg);
-                }
-                mIsAssociationInProgress = false;
-            }
-        };
-
         /**
          * Create a GattBroadcastService proxy object for interacting with the local
          * Bluetooth Service which handles the GattBroadcastService Profile
          */
-        private GattBroadcastServiceClientHandler(Context context, Looper looper) {
+        private GattBroadcastServiceClientHandler(Looper looper) {
             super(looper);
-            mContext = context;
-            doBind();
         }
 
         @Override
@@ -351,106 +301,33 @@
             Log.d(TAG, "Handler(): got msg=" + msg.what);
 
             switch (msg.what) {
-                case REGISTER_CALLBACK:
-                    registerCallbacks();
-                    break;
-                case UNREGISTER_CALLBACK:
-                    deRegisterCallbacks();
-                    if (mIsCountdownLatchEnabled) {
-                        mDeinitSignal.countDown();
-                        mIsCountdownLatchEnabled = false;
-                    }
-                    break;
                 case CONFIGURE_BROADCAST_RECEIVER_ASSOCIATION:
-                    boolean enable = (boolean) msg.obj;
-                    configureBroadcastReceiverAssociation(enable);
+                    Boolean enable = (Boolean) msg.obj;
+                    if(enable) {
+                        Intent intent_to_configure_BRA = new Intent(
+                                BroadcastAudioAppActivity.ACTION_BAT_BRA_ENABLE);
+                        sendBroadcast(intent_to_configure_BRA);
+                    } else {
+                        Intent intent_to_configure_BRA = new Intent(
+                                BroadcastAudioAppActivity.ACTION_BAT_BRA_DISABLE);
+                        sendBroadcast(intent_to_configure_BRA);
+                    }
                     break;
                 case ASSOCIATE_BCA_RECEIVER:
                     BluetoothDevice device = (BluetoothDevice) msg.obj;
-                    associateBCAReceiver(device);
+                    Intent intent_to_associate_BCA_Receiver = new Intent(
+                            BroadcastAudioAppActivity.ACTION_BAT_ASSOCIATE_BCA_RECEIVER);
+                    intent_to_associate_BCA_Receiver.putExtra(
+                            BluetoothDevice.EXTRA_DEVICE, device);
+                    sendBroadcast(intent_to_associate_BCA_Receiver);
                     break;
                 default:
                     break;
             }
         }
 
-        boolean doBind() {
-            Log.v(TAG, " doBind ");
-            Intent intent = new Intent().setClass(mContext, GattBroadcastService.class);
-            if (!mContext.bindServiceAsUser(intent, mConnection, 0,
-                    android.os.Process.myUserHandle())) {
-                Log.e(TAG, "Could not bind to Bluetooth gatt Service with intent" + intent);
-                return false;
-            }
-            return true;
-        }
-
         void close() {
             Log.v(TAG, " close ");
-            synchronized (mConnection) {
-                if (mService != null) {
-                    try {
-                        mContext.unbindService(mConnection);
-                        mService = null;
-                    } catch (Exception re) {
-                        Log.e(TAG, "", re);
-                    }
-                }
-            }
-        }
-
-        private boolean associateBCAReceiver(BluetoothDevice device) {
-            Log.v(TAG, " associateBCAReceiver ");
-            try {
-                if (mService != null) {
-                    mService.associateBCAReceiver(device);
-                    return true;
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to associate BCA Receiver " + e);
-            }
-            return false;
-        }
-
-        private boolean registerCallbacks() {
-            Log.v(TAG, " registerCallbacks ");
-            try {
-                if (mService != null) {
-                    mService.registerCallbacks(mServiceCallbacks);
-                    return true;
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to register Callbacks" + e);
-            }
-            return false;
-        }
-
-        private boolean deRegisterCallbacks() {
-            Log.v(TAG, " deRegisterCallbacks ");
-            try {
-                if (mService != null) {
-                    mService.deRegisterCallbacks(mServiceCallbacks);
-                    return true;
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to deRegister Callbacks" + e);
-                return false;
-            }
-            return false;
-        }
-
-        private boolean configureBroadcastReceiverAssociation(boolean enable) {
-            Log.v(TAG, " configureBroadcastReceiverAssociation ");
-
-            try {
-                if (mService != null) {
-                    mService.configureBroadcastReceiverAssociation(enable);
-                    return true;
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to configure Broadcast Receiver Association" + e);
-            }
-            return false;
         }
     }
-}
+}
\ No newline at end of file
diff --git a/BATestApp/src/org/codeaurora/bluetooth/batestapp/IGattBroadcastService.aidl b/BATestApp/src/org/codeaurora/bluetooth/batestapp/IGattBroadcastService.aidl
deleted file mode 100644
index c75dd09..0000000
--- a/BATestApp/src/org/codeaurora/bluetooth/batestapp/IGattBroadcastService.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials provided
- *      with the distribution.
- *    * Neither the name of The Linux Foundation nor the names of its
- *      contributors may be used to endorse or promote products derived
- *      from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codeaurora.bluetooth.batestapp;
-
-import android.bluetooth.BluetoothDevice;
-import org.codeaurora.bluetooth.batestapp.IGattBroadcastServiceCallback;
-
-/**
- * API for interacting with GattBroadcastService
- * @hide
- */
-
-interface IGattBroadcastService
-{
-    void registerCallbacks(in IGattBroadcastServiceCallback cb);
-    void deRegisterCallbacks(in IGattBroadcastServiceCallback cb);
-    void configureBroadcastReceiverAssociation(in boolean enable);
-    void associateBCAReceiver(in BluetoothDevice device);
-}
diff --git a/BATestApp/src/org/codeaurora/bluetooth/batestapp/IGattBroadcastServiceCallback.aidl b/BATestApp/src/org/codeaurora/bluetooth/batestapp/IGattBroadcastServiceCallback.aidl
deleted file mode 100644
index 00bc22c..0000000
--- a/BATestApp/src/org/codeaurora/bluetooth/batestapp/IGattBroadcastServiceCallback.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials provided
- *      with the distribution.
- *    * Neither the name of The Linux Foundation nor the names of its
- *      contributors may be used to endorse or promote products derived
- *      from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codeaurora.bluetooth.batestapp;
-
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.le.ScanResult;
-
-/**
- * Callback definitions for interacting with GattBroadcastService
- * @hide
- */
-
-interface IGattBroadcastServiceCallback {
-    void onFoundOnLostBCAReceiver(in ScanResult result, in boolean onfound);
-    void onConfiguredBroadcastReceiverAssociation(in int status);
-    void onAssociatedBCAReceiver(in BluetoothDevice device, in int status);
-}
diff --git a/BATestApp/src/org/codeaurora/bluetooth/batestapp/RecyclerViewListener.java b/BATestApp/src/org/codeaurora/bluetooth/batestapp/RecyclerViewListener.java
deleted file mode 100644
index 44ec03d..0000000
--- a/BATestApp/src/org/codeaurora/bluetooth/batestapp/RecyclerViewListener.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials provided
- *      with the distribution.
- *    * Neither the name of The Linux Foundation nor the names of its
- *      contributors may be used to endorse or promote products derived
- *      from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codeaurora.bluetooth.batestapp;
-
-import android.Manifest;
-import android.app.Activity;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.support.v4.content.ContextCompat;
-import android.util.Log;
-import android.widget.Toast;
-
-public interface RecyclerViewListener {
-    void onRecylerViewItemClicked(int clickedPos);
-}
diff --git a/BATestApp/src/org/codeaurora/bluetooth/batestapp/Utils.java b/BATestApp/src/org/codeaurora/bluetooth/batestapp/Utils.java
deleted file mode 100644
index 58918b0..0000000
--- a/BATestApp/src/org/codeaurora/bluetooth/batestapp/Utils.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *    * Redistributions of source code must retain the above copyright
- *      notice, this list of conditions and the following disclaimer.
- *    * Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials provided
- *      with the distribution.
- *    * Neither the name of The Linux Foundation nor the names of its
- *      contributors may be used to endorse or promote products derived
- *      from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.codeaurora.bluetooth.batestapp;
-
-import android.content.Context;
-import android.widget.Toast;
-
-public class Utils {
-
-    static final String TAG="BAAPP ";
-    public static void toast(Context ctx, String msg) {
-        Toast.makeText(ctx, msg, Toast.LENGTH_SHORT).show();
-    }
-}
diff --git a/packages_apps_bluetooth_ext/src/ba/BATService.java b/packages_apps_bluetooth_ext/src/ba/BATService.java
index b658a67..49fcdd3 100644
--- a/packages_apps_bluetooth_ext/src/ba/BATService.java
+++ b/packages_apps_bluetooth_ext/src/ba/BATService.java
@@ -30,38 +30,37 @@
 package com.android.bluetooth.ba;
 
 import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothBATransmitter;
-import android.bluetooth.BluetoothBAStreamServiceRecord;
-import android.bluetooth.BluetoothBAEncryptionKey;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothA2dp;
 
-import android.bluetooth.IBluetoothBATransmitter;
+import com.android.bluetooth.ba.BluetoothBAStreamServiceRecord;
+import com.android.bluetooth.ba.BluetoothBAEncryptionKey;
+import com.android.bluetooth.btservice.ProfileService;
+import com.android.bluetooth.a2dp.A2dpService;
+import com.android.bluetooth.hfp.HeadsetService;
+import com.android.bluetooth.Utils;
+
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.media.AudioManager;
 import android.os.Bundle;
-import android.provider.Settings;
+import android.os.Binder;
 import android.os.SystemProperties;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.util.Log;
-import com.android.bluetooth.btservice.ProfileService;
-import com.android.bluetooth.a2dp.A2dpService;
-import com.android.bluetooth.hfp.HeadsetService;
-import com.android.bluetooth.Utils;
+import android.provider.Settings;
+import android.media.AudioManager;
 
-import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import java.nio.ByteBuffer;
 
 /**
  * Provides Bluetooth Broadcast Audio profile, as a service in
@@ -69,41 +68,217 @@
  * @hide
  */
 public class BATService extends ProfileService {
+
     private static final boolean DBG = true;
-    private static final String TAG="BATService";
+    private static final String TAG = "BATService";
 
     private static final int NUM_SERIVCE_RECORD = 1;
     private static final long STREAM_ID_48 = 1;
     // currently we are using 512(fr_samples),186(frame_size),frequency.
     // check GattService specification for more details
-    //private static final long   CODEC_CONFIG_CELT = (long)0x020000BA0100;
+    //private static final long  CODEC_CONFIG_CELT = (long)0x020000BA0100;
     // Messages
-    public static final int MESSAGE_BAT_STATE_CHANGE_REQ = 1;
-    public static final int MESSAGE_BAT_REFRESH_ENC_KEY_REQ = 2;
-    public static final int MESSAGE_BAT_VOL_CHANGE_REQ = 3;
+    private final int MESSAGE_BAT_STATE_CHANGE_REQ = 1;
+    private final int MESSAGE_BAT_REFRESH_ENC_KEY_REQ = 2;
+    private final int MESSAGE_BAT_VOL_CHANGE_REQ = 3;
 
-    public static final int MESSAGE_BAT_STATE_CHANGE_EVT = 101;
-    public static final int MESSAGE_BAT_ENC_CHANGE_EVT = 102;
-    public static final int MESSAGE_BAT_DIV_CHANGE_EVT = 103;
-    public static final int MESSAGE_BAT_STREAMING_ID_EVT = 104;
+    private final int MESSAGE_BAT_STATE_CHANGE_EVT = 101;
+    private final int MESSAGE_BAT_ENC_CHANGE_EVT = 102;
+    private final int MESSAGE_BAT_DIV_CHANGE_EVT = 103;
+    private final int MESSAGE_BAT_STREAMING_ID_EVT = 104;
 
-    private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
-    public static final String mBAAddress = "CE:FA:CE:FA:CE:FA";
-    public static BluetoothDevice mBADevice;
+    private final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
+    static final String BLUETOOTH_PERM_ADMIN = android.Manifest.permission.BLUETOOTH_ADMIN;
+    public static final String mBAAddress = "FA:CE:FA:CE:FA:CE";
+    private BluetoothDevice mBADevice;
     // we will listen for vol change intent from audio manager.
     // this intent is called in all following 3 cases
     // 1 - Local vol changing when there is no abs vol
     // 2 - Local vol changes if abs vol not supported
     // 3 - Vol changed from remote if abs vol is supported
+
+    /**
+     * Intent used to update state change of Broadcast Audio Transmitter.
+     *
+     * This intent will have 2 extras:
+     * #EXTRA_STATE - The current state of the profile.
+     * #EXTRA_PREVIOUS_STATE - The previous state of the profile.
+     *
+     * value of states can be any of
+     * STATE_DISABLED: Broadcast Audio is disabled.
+     * STATE_PAUSED:   Broadcast Audio is enabled but streaming is paused.
+     * STATE_PLAYING:  Broadcast Audio is enabled but streaming is ongoing.
+     *
+     */
+    protected static final String ACTION_BAT_STATE_CHANGED =
+            "com.android.bluetooth.bat.profile.action.BA_STATE_CHANGED";
+    protected static final String EXTRA_STATE =
+            "com.android.bluetooth.bat.profile.extra.STATE";
+    protected static final String EXTRA_PREVIOUS_STATE =
+            "com.android.bluetooth.bat.profile.extra.PREV_STATE";
+
+     /**
+     * Intent is used to update state change of Broadcast Receiver Association.
+     *
+     * This intent will have 1 extra:
+     * #EXTRA_STATUS – status code
+     *
+     * value of states can be any of
+     *
+     * BRA_ENABLED_SUCESSS (0)
+     * BRA_ENABLED_FAILED (1)
+     * BRA_DISABLED_SUCESSS (2)
+     * BRA_DISABLED_FAILED(3)
+     */
+    protected static final String ACTION_BAT_BRA_STATE_CHANGED =
+            "com.android.bluetooth.bat.profile.action.BRA_STATE_CHANGED";
+    protected static final String EXTRA_STATUS =
+            "com.android.bluetooth.bat.profile.extra.STATUS";
+
+    /**
+     * Intent is used to for updating  Broadcast Audio Receiver info, after Broadcast audio receiver is Lost or Found.
+     *
+     * This intent will have 2 extras:
+     * #EXTRA_SCAN_RESULT – Scan Result for particular device.
+     * #EXTRA_ONFOUND –  true if device found, false if device lost.
+     *
+     */
+    protected static final String ACTION_BAT_ONFOUND_ONLOST_BCA_RECEIVER =
+            "com.android.bluetooth.bat.profile.action.ONFOUND_ONLOST_BCA_RECEIVER";
+    protected static final String EXTRA_SCAN_RESULT =
+            "com.android.bluetooth.bat.profile.extra.EXTRA_SCAN_RESULT";
+    protected static final String EXTRA_ONFOUND =
+            "com.android.bluetooth.bat.profile.extra.EXTRA_ONFOUND";
+
+    /**
+     * Intent is used to for updating Broadcast Audio Aeceiver info, after a Broadcast audio receiver is associated.
+     *
+     * This intent will have 2 extras:
+     * #EXTRA_DEVICE–  BluetoothDevice info
+     * #EXTRA_STATUS – Status code
+     *
+     *  value of status code can be any of
+     *
+     *  ASSOCIATE_BCA_RECEIVER_SUCCESS(4)
+     *  ASSOCIATE_BCA_RECEIVER_FAILED(5)
+     */
+    protected static final String ACTION_BAT_ON_ASSOCIATED_BCA_RECEIVER =
+            "com.android.bluetooth.bat.profile.action.ON_ASSOCIATED_BCA_RECEIVER";
+
+    /**
+     * Intent is used, when Broadcast Audio Encryption Key is refreshed.
+     *
+     */
+    private final String ACTION_BAT_ENCRYPTION_KEY_REFRESHED =
+            "com.android.bluetooth.bat.profile.action.ENCRYPTION_KEY_REFRESHED";
+    private final String ACTION_BAT_ENCRYPTION_KEY_REFRESH =
+            "com.android.bluetooth.bat.profile.action.ENCRYPTION_KEY_REFRESH";
+
+    /**
+     * Intents are used to enable/disable Broadcast audio
+     */
+    private final String ACTION_BAT_BA_ENABLE =
+            "com.android.bluetooth.bat.profile.action.BA_ENABLE";
+    private final String ACTION_BAT_BA_DISABLE =
+            "com.android.bluetooth.bat.profile.action.BA_DISABLE";
+
+    /**
+     * Intent used to update encryption key .
+     *
+     * This intent will have 1 extra:
+     * #EXTRA_ENCRYPTION_KEY - The current value of encryption key.
+     *
+     * value of EncyptionKey would be 128-bit value. This value would change
+     * on every new BA session. We will send BluetoothBAEncryptionKey object.
+     *
+     */
+    protected static final String ACTION_BAT_ENCRYPTION_KEY_CHANGED =
+            "com.android.bluetooth.bat.profile.action.BA_ENC_KEY_CHANGED";
+    protected static final String EXTRA_ECNRYPTION_KEY =
+            "com.android.bluetooth.bat.profile.extra.ENC_KEY";
+
+    /**
+     * Intent used to update DIV value .
+     *
+     * This intent will have 1 extras:
+     * #EXTRA_DIV_VALUE - The current value of DIV.
+     *
+     * value of DIV would be 2 byte value. This value would change
+     * on every new BA session. We will send integer value.
+     *
+     */
+    protected static final String ACTION_BAT_DIV_CHANGED =
+            "com.android.bluetooth.bat.profile.action.BA_DIV_CHANGED";
+    protected static final String EXTRA_DIV_VALUE =
+            "com.android.bluetooth.bat.profile.extra.DIV";
+
+    /**
+     * Intent used to update  active stream id for Broadcast Audio Transmitter.
+     *
+     * This intent will have 1 extra:
+     * #EXTRA_STREAM_ID - The active streaming id.
+     *
+     * value of states can be any of
+     * 0: Broadcast Audio is not in STATE_PLAYING.
+     * valid streaming id:   Valid streaming id if BA is in STATE_PLAYING.
+     */
+    protected static final String ACTION_BAT_STREAMING_ID_CHANGED =
+            "com.android.bluetooth.bat.profile.action.BA_STR_ID_CHANGED";
+    protected static final String EXTRA_STREAM_ID =
+            "com.android.bluetooth.bat.profile.extra.STR_ID";
+
+    /**
+     * Intent used to update  Vendor Specific AVRCP Command.
+     *
+     * This intent will be sent whenever there is Vendor Specific AVRCP command
+     * received from primary headset.
+     *
+     * This intent will have 2 extra:
+     * #EXTRA_AVRCP_VS_ENABLE_BA - value describing enable/disable of BA.
+     * #EXTRA_AVRCP_VS_ENABLE_RA - value describing enable/disable of receiver
+     *                              association mode.
+     *
+     * value of states can be any of
+     * 0: Disable  BA/RA.
+     * 1: ENABLE  BA/RA.
+     */
+    private final String ACTION_BAT_AVRCP_VS_CMD =
+            "com.android.bluetooth.bat.profile.action.BA_AVRCP_VS_CMD";
+    private final String EXTRA_AVRCP_VS_ENABLE_BA =
+            "com.android.bluetooth.bat.profile.extra.ENABLE_BA";
+    private final String EXTRA_AVRCP_VS_ENABLE_RA =
+            "com.android.bluetooth.bat.profile.extra.ENABLE_RA";
+    protected static final String ACTION_BAT_BRA_ENABLE =
+            "com.android.bluetooth.bat.profile.action.BRA_ENABLE";
+    public static final String ACTION_BAT_BRA_DISABLE =
+            "com.android.bluetooth.bat.profile.action.BRA_DISABLE";
+    protected static final String ACTION_BAT_ASSOCIATE_BCA_RECEIVER =
+            "com.android.bluetooth.bat.profile.action.ASSOCIATE_BCA_RECEIVER";
+
+    protected static final int STATE_DISABLED = 0;
+    protected static final int STATE_PAUSED = 1;
+    protected static final int STATE_PLAYING = 2;
+    private final int ENABLE_BA_TRANSMITTER = 0;
+    private final int DISABLE_BA_TRANSMITTER = 1;
+    private final int INVALID_DIV = 0xFFFF;
+    public static int BA_TRANSMITTER = 23;      // Added to access in Config.java
+
     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(AudioManager.VOLUME_CHANGED_ACTION)) {
+
+            String action = intent.getAction();
+            Log.d(TAG," action: " + action);
+
+            if(action == null)
+                return;
+            if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
                 Log.d(TAG," onReceive  AudioManager Vol Changed");
                 int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
                 Log.d(TAG," streamType = " + streamType);
                 if (streamType == AudioManager.STREAM_MUSIC) {
-                    int streamValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
+                    int streamValue = intent.getIntExtra(
+                            AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
                     int streamPrevValue = intent.getIntExtra(
                             AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, -1);
                     Log.d(TAG," prevVol = " + streamPrevValue + " streamVol = " + streamValue);
@@ -113,6 +288,22 @@
                     mMsgHandler.obtainMessage(MESSAGE_BAT_VOL_CHANGE_REQ,
                             streamValue,streamValue).sendToTarget();
                 }
+            } else if (action.equals(ACTION_BAT_BA_ENABLE)) {
+                setBATState(ENABLE_BA_TRANSMITTER);
+            } else if (action.equals(ACTION_BAT_BA_DISABLE)) {
+                setBATState(DISABLE_BA_TRANSMITTER);
+            } else if (action.equals(ACTION_BAT_ENCRYPTION_KEY_REFRESH)) {
+               refreshEncryptionKey();
+            } else if (action.equals(BluetoothAdapter.ACTION_BLE_STATE_CHANGED)) {
+                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+                        BluetoothAdapter.ERROR);
+                int prevState = intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE,
+                        BluetoothAdapter.ERROR);
+                if (state == BluetoothAdapter.STATE_BLE_ON || state == BluetoothAdapter.STATE_ON) {
+                    Log.d(TAG,"ACTION_BLE_STATE_CHANGED state: " + state);
+                    mGattBroadcastService = new GattBroadcastService();
+                    mGattBroadcastService.start(getApplicationContext());
+                }
             }
         }
     };
@@ -128,6 +319,8 @@
     private BATMessageHandler mMsgHandler;
     private static BATService sBATService;
     private BluetoothAdapter mAdapter;
+    private GattBroadcastService mGattBroadcastService;
+
     // we need pending state only during transition from enable/disable.
     // no need for statemachine, at this point. Can be manager with a variable.
 
@@ -139,6 +332,15 @@
         return new BluetoothBATBinder(this);
     }
 
+    private static class BluetoothBATBinder extends Binder implements IProfileServiceBinder {
+
+        BluetoothBATBinder(BATService service) {}
+
+        @Override
+        public void cleanup() {
+        }
+    }
+
     @Override
     protected boolean start() {
         Log.d(TAG, "BATService :: start + ");
@@ -156,7 +358,7 @@
         mMsgHandler = new BATMessageHandler(looper);
         Log.d(TAG," mMsgHandler = " + mMsgHandler);
         // initialize with default value.
-        mCurrDIV = BluetoothBATransmitter.INVALID_DIV;
+        mCurrDIV = INVALID_DIV;
         byte[] mEncryptionKey = new byte[BluetoothBAEncryptionKey.ENCRYPTION_KEY_LENGTH];
         mCurrEncryptionKey = new BluetoothBAEncryptionKey(mEncryptionKey,
                 BluetoothBAEncryptionKey.SECURITY_KEY_TYPE_PRIVATE);
@@ -183,21 +385,26 @@
                 BluetoothBAStreamServiceRecord.BSSR_SAMPLE_SIZE_16_BIT);
         mServiceRecord.addServiceRecordValue(STREAM_ID_48,
                 BluetoothBAStreamServiceRecord.BSSR_TYPE_AFH_UPDATE_METHOD_ID,
-                BluetoothBAStreamServiceRecord.BSSR_AFH_CHANNEL_MAP_UPDATE_METHOD_TRIGGERED_SYNC_TRAIN);
+                BluetoothBAStreamServiceRecord
+                .BSSR_AFH_CHANNEL_MAP_UPDATE_METHOD_TRIGGERED_SYNC_TRAIN);
         mServiceRecord.addServiceRecordValue(STREAM_ID_48,
                 BluetoothBAStreamServiceRecord.BSSR_TYPE_CODEC_CONFIG_CELT_FREQ_ID,
                 BluetoothBAStreamServiceRecord.BSSR_CODEC_FREQ_48KHZ);
         mServiceRecord.addServiceRecordValue(STREAM_ID_48,
                 BluetoothBAStreamServiceRecord.BSSR_TYPE_CODEC_CONFIG_CELT_FRAME_SIZE_ID,(long)186);
         mServiceRecord.addServiceRecordValue(STREAM_ID_48,
-                BluetoothBAStreamServiceRecord.BSSR_TYPE_CODEC_CONFIG_CELT_FRAME_SAMPLES_ID, (long)512);
+                BluetoothBAStreamServiceRecord
+                .BSSR_TYPE_CODEC_CONFIG_CELT_FRAME_SAMPLES_ID, (long)512);
 
         IntentFilter filter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION);
+        filter.addAction(ACTION_BAT_BA_ENABLE);
+        filter.addAction(ACTION_BAT_BA_DISABLE);
+        filter.addAction(ACTION_BAT_ENCRYPTION_KEY_REFRESH);
+        filter.addAction(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
         registerReceiver(mBroadcastReceiver, filter);
         mMsgHandler.obtainMessage(MESSAGE_BAT_VOL_CHANGE_REQ,
                 mCurrVolLevel,mCurrVolLevel).sendToTarget();
         mBADevice = mAdapter.getRemoteDevice(mBAAddress);
-        Log.d(TAG, "BATService :: start - ");
         return true;
     }
 
@@ -210,6 +417,10 @@
             if(looper != null)
                 looper.quit();
         }
+
+        if(mGattBroadcastService != null) {
+            mGattBroadcastService.stop();
+        }
         Log.d(TAG, "BATService :: stop - ");
         return true;
     }
@@ -257,8 +468,6 @@
             if (DBG)  {
                 if (instance == null) {
                     Log.d(TAG, "sBATService(): service not available");
-                } else if (!instance.isAvailable()) {
-                    Log.d(TAG,"sBATService(): service is cleaning up");
                 }
             }
         }
@@ -268,7 +477,7 @@
         sBATService = null;
     }
 
-    public static String dumpMessageString(int message) {
+    private String dumpMessageString(int message) {
         String str = "UNKNOWN";
         switch (message) {
             case MESSAGE_BAT_STATE_CHANGE_REQ: str = "REQ_STATE_CHANGE"; break;
@@ -283,7 +492,7 @@
         return str;
     }
 
-    public static String dumpStateString ( int state) {
+    private String dumpStateString ( int state) {
         String str = "UNKNOWN";
         switch (state) {
             case BA_STACK_STATE_IDLE: str = "BT_STACK_STATE_IDLE"; break;
@@ -304,7 +513,8 @@
         // when state changes from PENDING to IDLE, send A2DP Connected -> Disconnected
         if((mPrevStackBATState == BA_STACK_STATE_PENDING) &&
                 (mCurrStackBATState == BA_STACK_STATE_IDLE)) {
-            intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTED);
+            intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE,
+                    BluetoothProfile.STATE_CONNECTED);
             intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED);
             updateConnectionState = true;
         }
@@ -382,43 +592,44 @@
         int broadcastSate;
         switch (mCurrStackBATState) {
             case BA_STACK_STATE_IDLE:
-                broadcastSate = BluetoothBATransmitter.STATE_DISABLED;
+                broadcastSate = STATE_DISABLED;
                 break;
             case BA_STACK_STATE_PAUSED:
-                broadcastSate = BluetoothBATransmitter.STATE_PAUSED;
+                broadcastSate = STATE_PAUSED;
                 break;
             case BA_STACK_STATE_STREAMING:
-                broadcastSate = BluetoothBATransmitter.STATE_PLAYING;
+                broadcastSate = STATE_PLAYING;
                 break;
             default:
                 // we don't want to send intent for other states.
                 return;
         }
         Log.d(TAG," broadcasting state = " + broadcastSate);
-        Intent intent = new Intent(BluetoothBATransmitter.ACTION_BAT_STATE_CHANGED);
-        intent.putExtra(BluetoothBATransmitter.EXTRA_STATE, broadcastSate);
-        sendBroadcast(intent);
+        Intent intent = new Intent(ACTION_BAT_STATE_CHANGED);
+        intent.putExtra(EXTRA_STATE, broadcastSate);
+        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, mPrevStackBATState);
+        sendBroadcast(intent, BLUETOOTH_PERM_ADMIN);
     }
 
     private void broadcastEncKeyUpdate(BluetoothBAEncryptionKey encKey) {
         Log.d(TAG," broadcastEncKeyUpdate ");
-        Intent intent = new Intent(BluetoothBATransmitter.ACTION_BAT_ENCRYPTION_KEY_CHANGED);
-        intent.putExtra(BluetoothBATransmitter.EXTRA_ECNRYPTION_KEY, encKey);
-        sendBroadcast(intent);
+        Intent intent = new Intent(ACTION_BAT_ENCRYPTION_KEY_CHANGED);
+        intent.putExtra(EXTRA_ECNRYPTION_KEY, encKey);
+        sendBroadcast(intent, BLUETOOTH_PERM_ADMIN);
     }
 
     private void broadcastDIVUpdate(int div) {
         Log.d(TAG," broadcastDIVUpdate div =  "+ div);
-        Intent intent = new Intent(BluetoothBATransmitter.ACTION_BAT_DIV_CHANGED);
-        intent.putExtra(BluetoothBATransmitter.EXTRA_DIV_VALUE, div);
-        sendBroadcast(intent);
+        Intent intent = new Intent(ACTION_BAT_DIV_CHANGED);
+        intent.putExtra(EXTRA_DIV_VALUE, div);
+        sendBroadcast(intent, BLUETOOTH_PERM_ADMIN);
     }
 
     private void broadcastStramIdpdate(int streamID) {
-        Log.d(TAG," broadcastStramIdpdate streamID =  "+ streamID);
-        Intent intent = new Intent(BluetoothBATransmitter.ACTION_BAT_STREAMING_ID_CHANGED);
-        intent.putExtra(BluetoothBATransmitter.EXTRA_STREAM_ID, streamID);
-        sendBroadcast(intent);
+        Log.d(TAG," broadcastStramIdpdate streamID =  " + streamID);
+        Intent intent = new Intent(ACTION_BAT_STREAMING_ID_CHANGED);
+        intent.putExtra(EXTRA_STREAM_ID, streamID);
+        sendBroadcast(intent, BLUETOOTH_PERM_ADMIN);
     }
 
     // this api checks if abs vol is supported by AVRCP with any of the connected devices
@@ -497,12 +708,12 @@
     }
 
     // service level apis to be called from native callbacks
-    public void processBAStateUpdate(int newState) {
+    private void processBAStateUpdate(int newState) {
         Log.d(TAG," processBAStateUpdate newState = " + dumpStateString(newState));
         mMsgHandler.obtainMessage(MESSAGE_BAT_STATE_CHANGE_EVT, newState,0).sendToTarget();
     }
 
-    public void processEncryptionKeyUpdate(int size, byte[] enc_key) {
+    private void processEncryptionKeyUpdate(int size, byte[] enc_key) {
         Log.d(TAG," processEncryptionKeyUpdate size = " + size);
         Bundle data =  new Bundle();
         data.putByteArray("encKey", enc_key);
@@ -511,18 +722,18 @@
         mMsgHandler.sendMessage(msg);
     }
 
-    public void processDivUpdate(int size, byte[] div_key) {
+    private void processDivUpdate(int size, byte[] div_key) {
         Log.d(TAG," processDivUpdate size = " + size);
         ByteBuffer bb = ByteBuffer.wrap(div_key);
         Message msg = mMsgHandler.obtainMessage(MESSAGE_BAT_DIV_CHANGE_EVT, (int)bb.getShort(), 0);
         mMsgHandler.sendMessage(msg);
     }
 
-   public void processStreamIdUpdate(int streamId) {
+    private void processStreamIdUpdate(int streamId) {
        Log.d(TAG," processStreamIdUpdate streamID = " + streamId);
        Message msg = mMsgHandler.obtainMessage(MESSAGE_BAT_STREAMING_ID_EVT, (int)streamId, 0);
        mMsgHandler.sendMessage(msg);
-   }
+    }
 
     public boolean isBATActive() {
         Log.d(TAG," isBATActive  mCurrStackState = " + dumpStateString(mCurrStackBATState));
@@ -531,16 +742,6 @@
                 (mCurrStackBATState == BA_STACK_STATE_STREAMING));
     }
 
-    public boolean isBATPlaying() {
-        Log.d(TAG," isBATPlaying  mCurrStackState = " + dumpStateString(mCurrStackBATState));
-        return (mCurrStackBATState == BA_STACK_STATE_STREAMING);
-    }
-
-    public boolean isBATPaused() {
-        Log.d(TAG," isBATPaused  mCurrStackState = " + dumpStateString(mCurrStackBATState));
-        return (mCurrStackBATState == BA_STACK_STATE_PAUSED);
-    }
-
     public boolean isA2dpSuspendFromBA() {
         Log.d(TAG," isA2dpSuspendFromBA  mCurrStackState = "+
                         dumpStateString(mCurrStackBATState)
@@ -548,7 +749,7 @@
         return isCodecReconfigRequired;
     }
 
-    public boolean isA2dpPlaying() {
+    private boolean isA2dpPlaying() {
         A2dpService a2dpService = A2dpService.getA2dpService();
         if (a2dpService == null) {
             Log.d(TAG," isA2dpPlaying = false a2dpService null");
@@ -569,7 +770,7 @@
         return false;
     }
 
-    public boolean isCallActive() {
+    private boolean isCallActive() {
         HeadsetService headsetService = HeadsetService.getHeadsetService();
         if (headsetService == null) {
             Log.d(TAG," isCallActive = false HeadsetService null");
@@ -626,7 +827,7 @@
             switch(msg.what) {
                 case MESSAGE_BAT_STATE_CHANGE_REQ:
                     int newState = msg.arg1;
-                    if (newState == BluetoothBATransmitter.ENABLE_BA_TRANSMITTER) {
+                    if (newState == ENABLE_BA_TRANSMITTER) {
                         if (isCallActive()) {
                             Log.d(TAG," Call active, can't initilze BA ");
                             return;
@@ -637,8 +838,7 @@
                             //mAudioManager.setParameters("A2dpSuspended=true");
                         }
                         setBAStateNative(1);
-                    }
-                    if (newState == BluetoothBATransmitter.DISABLE_BA_TRANSMITTER) {
+                    } else if (newState == DISABLE_BA_TRANSMITTER) {
                         isCodecReconfigRequired = false;
                         setBAStateNative(0);
                     }
@@ -686,12 +886,12 @@
     public boolean setBATState(int newState) {
         Log.d(TAG," setBATState ( " + newState + ") currState = "
               + dumpStateString(mCurrStackBATState));
-        if((newState == BluetoothBATransmitter.ENABLE_BA_TRANSMITTER) &&
+        if((newState == ENABLE_BA_TRANSMITTER) &&
              (mCurrStackBATState != BA_STACK_STATE_IDLE)) {
             // we are already enabled, or in process of getting enabled
             return false;
         }
-        if((newState == BluetoothBATransmitter.DISABLE_BA_TRANSMITTER) &&
+        if((newState == DISABLE_BA_TRANSMITTER) &&
            (mCurrStackBATState == BA_STACK_STATE_IDLE)) {
             // we are already disabled
             return false;
@@ -701,7 +901,7 @@
             return false;
         if (mMsgHandler.hasMessages(MESSAGE_BAT_STATE_CHANGE_REQ))
             return false;
-        if (isCallActive() && (newState == BluetoothBATransmitter.ENABLE_BA_TRANSMITTER)) {
+        if (isCallActive() && (newState == ENABLE_BA_TRANSMITTER)) {
             Log.d(TAG," setBATState Call active, can't initilze BA ");
             return false;
         }
@@ -709,26 +909,26 @@
         return true;
     }
 
-    public int getBATState() {
-        int state = BluetoothBATransmitter.STATE_DISABLED;
+    protected int getBATState() {
+        int state = STATE_DISABLED;
         Log.d(TAG," getBATState = " + dumpStateString(mCurrStackBATState));
         switch (mCurrStackBATState) {
             case BA_STACK_STATE_IDLE:
             case BA_STACK_STATE_PENDING:
-                state = BluetoothBATransmitter.STATE_DISABLED;
+                state = STATE_DISABLED;
                 break;
             case BA_STACK_STATE_PAUSED:
             case BA_STACK_STATE_AUDIO_PENDING:
-                state = BluetoothBATransmitter.STATE_PAUSED;
+                state = STATE_PAUSED;
                 break;
             case BA_STACK_STATE_STREAMING:
-                state = BluetoothBATransmitter.STATE_PLAYING;
+                state = STATE_PLAYING;
                 break;
         }
         return state;
     }
 
-    public int getDIV() {
+    protected int getDIV() {
         Log.d(TAG," getDIV = " + mCurrDIV);
         if ((mCurrStackBATState == BA_STACK_STATE_IDLE) ||
             (mCurrStackBATState == BA_STACK_STATE_PENDING))
@@ -736,13 +936,13 @@
         return mCurrDIV;
     }
 
-    public long getStreamId() {
+    protected long getStreamId() {
         Log.d(TAG," getStreamId state = " + dumpStateString(mCurrStackBATState));
         // send same ID every time.
         return STREAM_ID_48;
     }
 
-    public BluetoothBAEncryptionKey getEncryptionKey() {
+    protected BluetoothBAEncryptionKey getEncryptionKey() {
         Log.d(TAG," getEncryptionKey state = " + dumpStateString(mCurrStackBATState));
         if ((mCurrStackBATState == BA_STACK_STATE_IDLE) ||
                 (mCurrStackBATState == BA_STACK_STATE_PENDING) )
@@ -750,7 +950,7 @@
         return mCurrEncryptionKey;
     }
 
-    public boolean refreshEncryptionKey() {
+    private boolean refreshEncryptionKey() {
         Log.d(TAG," refreshEncryptionKey state = " + dumpStateString(mCurrStackBATState));
         if (mCurrStackBATState == BA_STACK_STATE_IDLE)
             return false;
@@ -758,91 +958,10 @@
         return true;
     }
 
-    public BluetoothBAStreamServiceRecord getBAServiceRecord() {
+    protected BluetoothBAStreamServiceRecord getBAServiceRecord() {
         Log.d(TAG," getBAServiceRecord state = " + dumpStateString(mCurrStackBATState));
         return mServiceRecord;
     }
-    //Binder object: Must be static class or memory leak may occur
-    private static class BluetoothBATBinder extends IBluetoothBATransmitter.Stub
-        implements IProfileServiceBinder {
-        private BATService mService;
-
-        private BATService getService() {
-            if (!Utils.checkCaller()) {
-                Log.w(TAG,"A2dp call not allowed for non-active user");
-                return null;
-            }
-
-            if (mService != null && mService.isAvailable()) {
-                return mService;
-            }
-            return null;
-        }
-
-        BluetoothBATBinder(BATService svc) {
-            mService = svc;
-        }
-
-        public boolean setBATState(int state) {
-            BATService service = getService();
-            if(service == null) return false;
-            return service.setBATState(state);
-        }
-
-        public int getBATState() {
-            BATService service = getService();
-            if(service == null) return BluetoothBATransmitter.STATE_DISABLED;
-            return service.getBATState();
-        }
-
-        public int getDIV() {
-            BATService service = getService();
-            if(service == null) return 0;
-            return service.getDIV();
-        }
-
-        public long getStreamId() {
-            BATService service = getService();
-            if(service == null) return (long)0;
-            return service.getStreamId();
-        }
-
-        public BluetoothBAEncryptionKey getEncryptionKey() {
-            BATService service = getService();
-            if(service == null) return null;
-            return service.getEncryptionKey();
-        }
-
-        public boolean refreshEncryptionKey() {
-            BATService service = getService();
-            if(service == null) return false;
-            return service.refreshEncryptionKey();
-        }
-
-        public BluetoothBAStreamServiceRecord getBAServiceRecord() {
-            BATService service = getService();
-            if(service == null) return null;
-            return service.getBAServiceRecord();
-        }
-
-        public List<BluetoothDevice> getConnectedDevices() {
-            return new ArrayList<BluetoothDevice>();
-        }
-
-        public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-            return new ArrayList<BluetoothDevice>();
-        }
-
-        public int getConnectionState(BluetoothDevice device) {
-            return BluetoothProfile.STATE_DISCONNECTED;
-        }
-
-        @Override
-        public void cleanup() {
-            mService = null;
-        }
-
-    };
 
     private void onBATStateChanged(int newState) {
         Log.d(TAG," onBATStateChanged ( " + newState + " )");
@@ -873,11 +992,11 @@
     }
 
     // make these states in sync with values in hal
-    final static int BA_STACK_STATE_IDLE = 0;
-    final static int BA_STACK_STATE_PENDING = 1;// transitioining between IDLE and non-idle state.
-    final static int BA_STACK_STATE_PAUSED = 2;
-    final static int BA_STACK_STATE_STREAMING = 3;
-    final static int BA_STACK_STATE_AUDIO_PENDING = 4;// transitioning between Pu and Str
+    private final int BA_STACK_STATE_IDLE = 0;
+    private final int BA_STACK_STATE_PENDING = 1;// transitioining between IDLE and non-idle state.
+    private final int BA_STACK_STATE_PAUSED = 2;
+    private final int BA_STACK_STATE_STREAMING = 3;
+    private final int BA_STACK_STATE_AUDIO_PENDING = 4;// transitioning between Pu and Str
 
     private native static void classInitNative();
     private native static void initNative();
@@ -885,4 +1004,4 @@
     private native static void cleanupNative();
     private native static void setBAStateNative(int enable);
     private native static void setVolNative(int volLevel, int maxVolLevel);
-}
+}
\ No newline at end of file
diff --git a/packages_apps_bluetooth_ext/src/ba/BluetoothBAEncryptionKey.java b/packages_apps_bluetooth_ext/src/ba/BluetoothBAEncryptionKey.java
new file mode 100644
index 0000000..2c42c23
--- /dev/null
+++ b/packages_apps_bluetooth_ext/src/ba/BluetoothBAEncryptionKey.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.bluetooth.ba;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * Class used to identify 128 bit Encryption Key for BA.
+ *
+ * {@hide}
+ */
+public final class BluetoothBAEncryptionKey implements Parcelable {
+    public static final String TAG = "BluetoothBAEncryptionKey";
+
+    private int mFlagType;
+    public static int ENCRYPTION_KEY_LENGTH = 16;// key len in bytes
+    public static int SECURITY_KEY_TYPE_PRIVATE = 0x0001;
+    public static int SECURITY_KEY_TYPE_TEMP    = 0x0002;
+    public static int SECURITY_KEY_FORWARD_ENABLED     = 0x0080;
+    private byte[] mEncryptionKey = new byte[ENCRYPTION_KEY_LENGTH];
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        for (int k =0; k < ENCRYPTION_KEY_LENGTH; k++) {
+            out.writeByte(mEncryptionKey[k]);
+        }
+        out.writeInt(mFlagType);
+    }
+
+    public static final Parcelable.Creator<BluetoothBAEncryptionKey> CREATOR
+            = new Parcelable.Creator<BluetoothBAEncryptionKey>() {
+        public BluetoothBAEncryptionKey createFromParcel(Parcel in) {
+            return new BluetoothBAEncryptionKey(in);
+        }
+
+        public BluetoothBAEncryptionKey[] newArray(int size) {
+            return new BluetoothBAEncryptionKey[size];
+        }
+    };
+
+    private BluetoothBAEncryptionKey(Parcel in) {
+        for (int i = 0; i < ENCRYPTION_KEY_LENGTH; i++) {
+            mEncryptionKey[i] = in.readByte();
+        }
+        mFlagType = in.readInt();
+    }
+
+    /**
+     * Create a new BluetoothBAEncryptionKey object.
+     *
+     * @param byte array contianing encryption key
+     */
+    public BluetoothBAEncryptionKey(byte[] mEncKey, int flagType) {
+        for (int i = 0; i < ENCRYPTION_KEY_LENGTH; i++) {
+            mEncryptionKey[i] = mEncKey[i];
+        }
+        mFlagType = flagType;
+    }
+
+    /**
+     * Get the encryption key.
+     *
+     * @return byte array containing encryption key.
+     */
+    public byte[] getEncryptionKey() {
+        return mEncryptionKey;
+    }
+
+    public int getFlagType() {
+        return mFlagType;
+    }
+}
\ No newline at end of file
diff --git a/packages_apps_bluetooth_ext/src/ba/BluetoothBAStreamServiceRecord.java b/packages_apps_bluetooth_ext/src/ba/BluetoothBAStreamServiceRecord.java
new file mode 100644
index 0000000..173c532
--- /dev/null
+++ b/packages_apps_bluetooth_ext/src/ba/BluetoothBAStreamServiceRecord.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above
+ *     copyright notice, this list of conditions and the following
+ *     disclaimer in the documentation and/or other materials provided
+ *     with the distribution.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.bluetooth.ba;
+
+import android.util.Log;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.List;
+
+/**
+ * Class used to send Broadcast Audio Stream Service Records.
+ */
+public final class BluetoothBAStreamServiceRecord {
+    public static final String TAG = "BluetoothBAStreamServiceRecord";
+
+    public static final int BSSR_TYPE_STREAM_ID       = 0;
+    public static final int BSSR_TYPE_STREAM_ID_LEN   = 1;
+    // actual values would be returned
+
+    // security fields
+    public static final int BSSR_TYPE_SECURITY_ID     = 1;
+    public static final int BSSR_TYPE_SECURITY_ID_LEN = 2;
+    //This stream uses the private key
+    public static final long BSSR_SECURITY_KEY_TYPE_PRIVATE    = 0x0001;
+    //This stream uses the temporary key
+    public static final long BSSR_SECURITY_KEY_TYPE_TEMP       = 0x0002;
+    //This stream does not use encryption
+    public static final long BSSR_SECURITY_ENCRYPT_TYPE_NONE   = 0x0100;
+    //This stream uses AESCCM encryption
+    public static final long BSSR_SECURITY_ENCRYPT_TYPE_AESCCM = 0x0200;
+
+    // codec type fields
+    public static final int BSSR_TYPE_CODEC_TYPE_ID            = 2;
+    public static final int BSSR_TYPE_CODEC_TYPE_ID_LEN        = 1;
+    public static final long BSSR_CODEC_TYPE_CELT              = 0x01;       // CELT CODEC
+
+    // CELT config values, defined below.
+    public static final int BSSR_TYPE_CODEC_CONFIG_CELT_ID     = 3;// these values are further divided
+    // into 3 values freq, frame_size and frame_samples.
+    public static final int BSSR_TYPE_CODEC_CONFIG_CELT_ID_LEN = 6;
+
+    public static final int BSSR_TYPE_SCMST_SUPPORT_ID         = 5;
+    public static final int BSSR_TYPE_SCMST_SUPPORT_ID_LEN     = 1;
+    //The recipient must not copy the data in this stream
+    public static final long BSSR_SCMST_SUPPORT_COPY           = 0x01;
+    //The recipient must not forward the data in this stream.
+    public static final long BSSR_SCMST_SUPPORT_FORWARD        = 0x02;
+
+    // Erasure Coding values
+    public static final int BSSR_TYPE_ERASURE_CODE_ID     = 6;
+    public static final int BSSR_TYPE_ERASURE_CODE_ID_LEN = 1;
+    public static final long BSSR_ERASURE_CODE_NONE       = 0x00;//No erasure coding in this stream
+    public static final long BSSR_ERASURE_CODE_2_5        = 0x01;//The stream has a 2,5 coding scheme
+    public static final long BSSR_ERASURE_CODE_3_7        = 0x02;//The stream has a 3,7 coding scheme
+    public static final long BSSR_ERASURE_CODE_3_8        = 0x03;//The stream has a 3,8 coding scheme
+    public static final long BSSR_ERASURE_CODE_3_9        = 0x04;//The stream has a 3,9 coding scheme
+
+    public static final int BSSR_TYPE_CHANNELS_ID         = 7;
+    public static final int BSSR_TYPE_CHANNELS_ID_LEN     = 2;
+    public static final long BSSR_CHANNELS_MONO           = 0x0001;//This stream is mono
+    public static final long BSSR_CHANNELS_STEREO         = 0x0004;//This stream is stereo
+
+    public static final int BSSR_TYPE_SAMPLE_SIZE_ID      = 8;
+    public static final int BSSR_TYPE_SAMPLE_SIZE_ID_LEN  = 1;
+    public static final long BSSR_SAMPLE_SIZE_8_BIT       = 0x01;//This stream is 8-bit samples
+    public static final long BSSR_SAMPLE_SIZE_16_BIT      = 0x02;//This stream is 16-bit samples
+    public static final long BSSR_SAMPLE_SIZE_24_BIT      = 0x04;//This stream id 24-bit samples
+
+    public static final int BSSR_TYPE_AFH_UPDATE_METHOD_ID           = 9;
+    public static final int BSSR_TYPE_AFH_UPDATE_METHOD_ID_LEN       = 1;
+    //This stream does not support AFH channel map updates
+    public static final long BSSR_AFH_CHANNEL_MAP_UPDATE_METHOD_NONE = 0x00;
+    //This stream uses SCM to transport AFH channel map updates from broadcaster to receivers.
+    public static final long BSSR_AFH_CHANNEL_MAP_UPDATE_METHOD_SCM  = 0x01;
+    //This stream uses the triggered CSB sync train method to transport AFH channel map
+    // updates from broadcaster to receivers.
+    public static final long BSSR_AFH_CHANNEL_MAP_UPDATE_METHOD_TRIGGERED_SYNC_TRAIN = 0x02;
+
+    public static final int BSSR_TYPE_CODEC_CONFIG_CELT_FREQ_ID     = 10;
+    public static final int BSSR_TYPE_CODEC_CONFIG_CELT_FREQ_ID_LEN = 2;
+    public static final long BSSR_CODEC_FREQ_8KHZ                   = 0x0001;
+    public static final long BSSR_CODEC_FREQ_11025HZ                = 0x0002;
+    public static final long BSSR_CODEC_FREQ_12KHZ                  = 0x0004;
+    public static final long BSSR_CODEC_FREQ_16KHZ                  = 0x0008;
+    public static final long BSSR_CODEC_FREQ_22050HZ                = 0x0010;
+    public static final long BSSR_CODEC_FREQ_24KHZ                  = 0x0020;
+    public static final long BSSR_CODEC_FREQ_32KHZ                  = 0x0040;
+    public static final long BSSR_CODEC_FREQ_44100HZ                = 0x0080;
+    public static final long BSSR_CODEC_FREQ_48KHZ                  = 0x0100;
+    public static final long BSSR_CODEC_FREQ_64KHZ                  = 0x0200;
+    public static final long BSSR_CODEC_FREQ_88200HZ                = 0x0400;
+    public static final long BSSR_CODEC_FREQ_96KHZ                  = 0x0800;
+    public static final long BSSR_CODEC_FREQ_128KHZ                 = 0x1000;
+    public static final long BSSR_CODEC_FREQ_176400HZ               = 0x2000;
+    public static final long BSSR_CODEC_FREQ_192KHZ                 = 0x4000;
+
+    public static final int BSSR_TYPE_CODEC_CONFIG_CELT_FRAME_SIZE_ID        = 11;
+    public static final int BSSR_TYPE_CODEC_CONFIG_CELT_FRAME_SIZE_ID_LEN    = 2;
+    // actual values would be returned
+
+    public static final int BSSR_TYPE_CODEC_CONFIG_CELT_FRAME_SAMPLES_ID     = 12;
+    public static final int BSSR_TYPE_CODEC_CONFIG_CELT_FRAME_SAMPLES_ID_LEN = 2;
+    // actual values would be returned
+
+    /*
+    * Every single record will be a HashMap of a number of record.
+    * We will have a List of HashMap to send all possible values of stream records.
+    */
+    //private Map<Integer, Long> mServiceRecord = new HashMap<Integer, Long>();
+    int mNumRecords;
+    private List<Map<Integer, Long>> mServiceRecordList = new ArrayList<Map<Integer, Long>>();
+
+    /**
+     * Create a new BA Service Record Object.
+     *
+     * @param number of records
+     */
+    public BluetoothBAStreamServiceRecord(int numRec) {
+        mNumRecords = numRec;
+    }
+
+    /**
+     * Get number of records.
+     *
+     * @return number of records
+     */
+    public int getNumRecords() {
+        return mNumRecords;
+    }
+
+    /**
+     * Add a record value.
+     *
+     * @param streamId: streamId of the record.
+     * @param recordAttribId: one of the record attribute as mentioned above.
+     * @param recordAttribVal: one of the record attribute values as mentioned above.
+     */
+    public void addServiceRecordValue(Long streamId, int recordAttribId, Long recordAttribVal) {
+        // find streamId in the list.
+        if (!mServiceRecordList.isEmpty()) {
+            for (Map<Integer, Long> mServiceRecord: mServiceRecordList) {
+                if (mServiceRecord.containsKey(BSSR_TYPE_STREAM_ID) &&
+                        mServiceRecord.get(BSSR_TYPE_STREAM_ID).equals(streamId)) {
+                    mServiceRecord.put(recordAttribId, recordAttribVal);
+                    return;
+                }
+            }
+        }
+        // either list is empty or matching record not found.
+        Map<Integer, Long> mServiceRecord = new HashMap<Integer, Long>();
+        mServiceRecord.put(BSSR_TYPE_STREAM_ID, streamId);
+        mServiceRecord.put(recordAttribId, recordAttribVal);
+        mServiceRecordList.add(mServiceRecord);
+    }
+
+    /**
+     * Add a record .
+     *
+     * @param serviceRecord: a Map of service attribute id and attribute values.
+     */
+    public void addServiceRecord(Map<Integer, Long> mServiceRecord) {
+        // if a record with same stream_id is existing, we will remove old record and add new one.
+        // We are not going to change this record.
+        if(mServiceRecordList.isEmpty()) {
+            mServiceRecordList.add(mServiceRecord);
+            return;
+        }
+        // check if we have record with same stream id
+        for (Map<Integer, Long> mRecord: mServiceRecordList) {
+            if (mRecord.containsKey(BSSR_TYPE_STREAM_ID) &&
+                mRecord.get(BSSR_TYPE_STREAM_ID).equals(mServiceRecord.get(BSSR_TYPE_STREAM_ID))) {
+                // delete this record from List
+                mServiceRecordList.remove(mRecord);
+            }
+        }
+        // either record is not found, or removed.
+        mServiceRecordList.add(mServiceRecord);
+    }
+
+    /**
+     * Get record values.
+     *
+     * @param streamId: streamId of the record.
+     * @param recordAttribId: one of the record attribute as mentioned above.
+     * @return one of the record attribute values as mentioned above, 0 otherwise
+     */
+    public Long getServiceRecordValue(Long streamId, int recordAttribId) {
+        // find streamId in the list.
+        if (!mServiceRecordList.isEmpty()) {
+            for (Map<Integer, Long> mServiceRecord: mServiceRecordList) {
+                if (mServiceRecord.containsKey(BSSR_TYPE_STREAM_ID) &&
+                        mServiceRecord.get(BSSR_TYPE_STREAM_ID).equals(streamId)) {
+                    return mServiceRecord.get(recordAttribId);
+                }
+            }
+        }
+        // either list is empty or matching record not found.
+        return new Long(0);
+    }
+
+    /**
+     * Get record .
+     *
+     * @param streamId: streamId of the Record to be fetched.
+     * @return servicerecord if streamId matches, empty record otherwise;
+     */
+    public Map<Integer, Long> getServiceRecord( Long streamId) {
+        if(mServiceRecordList.isEmpty())
+            return null;
+        for (Map<Integer, Long> mServiceRecord: mServiceRecordList) {
+            if (mServiceRecord.containsKey(BSSR_TYPE_STREAM_ID) &&
+                    mServiceRecord.get(BSSR_TYPE_STREAM_ID).equals(streamId)) {
+                return mServiceRecord;
+            }
+        }
+        // can't find record, return empty record
+        return null;
+    }
+
+    /**
+     * Get all stored streamIds .
+     *
+     * @return array of all streamIds
+     */
+    public Long[] getStreamIds() {
+        if(mServiceRecordList.isEmpty())
+            return null;
+        Long[] streamIdList = new Long[mServiceRecordList.size()];
+        int k = 0;
+        for (Map<Integer, Long> mServiceRecord: mServiceRecordList) {
+            if (mServiceRecord.containsKey(BSSR_TYPE_STREAM_ID))
+                streamIdList[k++] = mServiceRecord.get(BSSR_TYPE_STREAM_ID);
+        }
+        return streamIdList;
+    }
+}
\ No newline at end of file
diff --git a/BATestApp/src/org/codeaurora/bluetooth/batestapp/GattBroadcastService.java b/packages_apps_bluetooth_ext/src/ba/GattBroadcastService.java
similarity index 77%
rename from BATestApp/src/org/codeaurora/bluetooth/batestapp/GattBroadcastService.java
rename to packages_apps_bluetooth_ext/src/ba/GattBroadcastService.java
index 71052ea..cef1810 100644
--- a/BATestApp/src/org/codeaurora/bluetooth/batestapp/GattBroadcastService.java
+++ b/packages_apps_bluetooth_ext/src/ba/GattBroadcastService.java
@@ -27,7 +27,7 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-package org.codeaurora.bluetooth.batestapp;
+package com.android.bluetooth.ba;
 
 import android.app.Service;
 
@@ -35,7 +35,6 @@
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.BluetoothManager;
-
 import android.bluetooth.BluetoothGatt;
 import android.bluetooth.BluetoothGattCallback;
 import android.bluetooth.BluetoothGattCharacteristic;
@@ -57,9 +56,8 @@
 import android.bluetooth.le.ScanResult;
 import android.bluetooth.le.ScanSettings;
 
-import android.bluetooth.BluetoothBAEncryptionKey;
-import android.bluetooth.BluetoothBAStreamServiceRecord;
-import android.bluetooth.BluetoothBATransmitter;
+import com.android.bluetooth.ba.BluetoothBAEncryptionKey;
+import com.android.bluetooth.ba.BluetoothBAStreamServiceRecord;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -70,20 +68,16 @@
 import android.os.IBinder;
 import android.os.ParcelUuid;
 import android.os.Message;
-import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.RemoteException;
-
+import android.os.Binder;
 import android.util.Log;
 
 import com.android.internal.util.IState;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
-
-import org.codeaurora.bluetooth.batestapp.IGattBroadcastService;
-import org.codeaurora.bluetooth.batestapp.IGattBroadcastServiceCallback;
-import org.codeaurora.bluetooth.batestapp.BAAudio;
+import com.android.bluetooth.btservice.ProfileService;
 
 import java.util.List;
 import java.util.UUID;
@@ -92,156 +86,119 @@
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 
-public class GattBroadcastService extends Service {
-    private static final String TAG = Utils.TAG + "GattBroadcastService";
+public class GattBroadcastService  {
+    private static final String TAG = "GattBroadcastService";
 
-    public static final UUID GATT_BROADCAST_SERVICE_UUID = UUID.fromString
+    private final UUID GATT_BROADCAST_SERVICE_UUID = UUID.fromString
             ("0000FE06-0000-1000-8000-00805F9B34FB");
-    public static final UUID BROADCAST_VERSION_UUID = UUID.fromString
+    private final UUID BROADCAST_VERSION_UUID = UUID.fromString
             ("0000BCA4-d102-11e1-9b23-00025b00a5a5");
-    public static final UUID BROADCAST_ADDRESS_UUID = UUID.fromString
+    private final UUID BROADCAST_ADDRESS_UUID = UUID.fromString
             ("0000BCA7-d102-11e1-9b23-00025b00a5a5");
-    public static final UUID BROADCAST_STATUS_UUID = UUID.fromString
+    private final UUID BROADCAST_STATUS_UUID = UUID.fromString
             ("0000BCA5-d102-11e1-9b23-00025b00a5a5");
-    public static final UUID BROADCAST_SECKEY_UUID = UUID.fromString
+    private final UUID BROADCAST_SECKEY_UUID = UUID.fromString
             ("0000BCAC-d102-11e1-9b23-00025b00a5a5");
-    public static final UUID BROADCAST_STREAM_SERVICE_RECORDS_UUID = UUID.fromString
+    private final UUID BROADCAST_STREAM_SERVICE_RECORDS_UUID = UUID.fromString
             ("0000BCA6-d102-11e1-9b23-00025b00a5a5");
-    public static final UUID BROADCAST_IDENTIFIER_UUID = UUID.fromString
+    private final UUID BROADCAST_IDENTIFIER_UUID = UUID.fromString
             ("0000BCA8-d102-11e1-9b23-00025b00a5a5");
-    //status codes
-    public static final int BRA_ENABLED_SUCESSS = 0;
-    public static final int BRA_ENABLED_FAILED = 1;
-    public static final int BRA_DISABLED_SUCESSS = 2;
-    public static final int BRA_DISABLED_FAILED = 3;
-    public static final int ASSOCIATE_BCA_RECEIVER_SUCCESS = 4;
-    public static final int ASSOCIATE_BCA_RECEIVER_FAILED = 5;
 
+    // Status Codes
+    private final int BRA_ENABLED_SUCCESS = 0;
+    private final int BRA_ENABLED_FAILED = 1;
+    private final int BRA_DISABLED_SUCCESS = 2;
+    private final int BRA_DISABLED_FAILED = 3;
+    private final int ASSOCIATE_BCA_RECEIVER_SUCCESS = 4;
+    private final int ASSOCIATE_BCA_RECEIVER_FAILED = 5;
 
-    private static final int FETCH_OWN_RANDOM_ADDRESS = 0;
-    private static final int NOTIFY_CB_ASSOCIATE_BCA_RECEIVER = 1;
-    private static final int NOTIFY_CB_CONFIGURE_BRA = 2;
-    private static final int NOTIFY_CB_ONLOST_ONFOUND_RECEIVER = 3;
-    private static final int HANDLER_ARG_NOT_USED = -1;
+    private final int FETCH_OWN_RANDOM_ADDRESS = 0;
+    private final int NOTIFY_CB_ASSOCIATE_BCA_RECEIVER = 1;
+    private final int NOTIFY_CB_CONFIGURE_BRA = 2;
+    private final int NOTIFY_CB_ONLOST_ONFOUND_RECEIVER = 3;
+    private final int HANDLER_ARG_NOT_USED = -1;
+    private final int LE_DEVICE_NAME_MAX_LENGTH = 15;
 
-    private static final int LE_DEVICE_NAME_MAX_LENGTH = 15;
-
-    public BluetoothManager mBluetoothManager;
-    public BAAudio mBAAudio;
-    public BleScanner mBleScanner;
-    public BleAdvertiser mBleAdvertiser;
+    private BluetoothManager mBluetoothManager;
+    private BATService mBATService;
+    private BleScanner mBleScanner;
+    private BleAdvertiser mBleAdvertiser;
     private BluetoothAdapter mBluetoothAdapter;
     private GattBroadcastServiceReceiver mReceiver;
     private GattBroadcastServiceStateMachine mStateMachine;
     private boolean mIsBAPairing = false;
     private BluetoothDevice mDevice = null;
-    private IGattBroadcastServiceCallback mGattBroadcastServiceCallback = null;
     private Context mContext;
     private GattBroadcastServiceMessageHandler mSessionHandler = null;
 
-    private final IGattBroadcastService.Stub mBinder = new IGattBroadcastService.Stub() {
-
-        public void registerCallbacks(IGattBroadcastServiceCallback cb) {
-            Log.i(TAG, "registerCallbacks");
-            if (mGattBroadcastServiceCallback == null)
-                mGattBroadcastServiceCallback = cb;
+    private void configureBroadcastReceiverAssociation(boolean enable) {
+        Log.i(TAG, "configureBroadcastReceiverAssociation :" + enable);
+        //Do not forward BRA Enable/Disable request to state machine, if BT is not on.
+        if (isBluetoothLeOn() && mStateMachine != null) {
+            mStateMachine.sendMessage(GattBroadcastServiceStateMachine
+                    .CONFIGURE_BROADCAST_RECEIVER_ASSOCIATION, enable);
+        } else if (mSessionHandler != null) {
+            int status = enable ? BRA_ENABLED_FAILED: BRA_DISABLED_SUCCESS;
+            mSessionHandler.sendMessage(
+                    mSessionHandler.obtainMessage(NOTIFY_CB_CONFIGURE_BRA, status));
+        } else {
+            Log.i(TAG, "mSessionHandler is null");
         }
+    }
 
-        public void deRegisterCallbacks(IGattBroadcastServiceCallback cb) {
-            Log.i(TAG, "deRegisterCallbacks");
-            if (mGattBroadcastServiceCallback == cb)
-                mGattBroadcastServiceCallback = null;
+    private void associateBCAReceiver(BluetoothDevice device) {
+        Log.i(TAG, "associateBCAReceiver :" + device);
+         //Do not forward associate BCA Receiver request to state machine, if BT is not on.
+        if (isBluetoothLeOn() && mStateMachine != null) {
+            mStateMachine.sendMessage(GattBroadcastServiceStateMachine
+                    .ASSOCIATE_BCA_RECEIVER, device);
+        } else if (mSessionHandler != null) {
+            mSessionHandler.sendMessage(
+                    mSessionHandler.obtainMessage(NOTIFY_CB_ASSOCIATE_BCA_RECEIVER,
+                            ASSOCIATE_BCA_RECEIVER_FAILED, HANDLER_ARG_NOT_USED, device));
+        } else {
+            Log.i(TAG, "mSessionHandler is null");
         }
+    }
 
-        public void configureBroadcastReceiverAssociation(boolean enable) {
-            Log.i(TAG, "configureBroadcastReceiverAssociation :"+enable);
-            //Do not forward BRA Enable/Disable request to state machine, if BT is not on.
-            if (isBluetoothLeOn() && mStateMachine != null) {
-                mStateMachine.sendMessage(GattBroadcastServiceStateMachine
-                        .CONFIGURE_BROADCAST_RECEIVER_ASSOCIATION, enable);
-            } else if (mSessionHandler != null) {
-                int status = enable ? BRA_ENABLED_FAILED: BRA_DISABLED_SUCESSS;
-                mSessionHandler.sendMessage(
-                        mSessionHandler.obtainMessage(NOTIFY_CB_CONFIGURE_BRA, status));
-            } else {
-                Log.i(TAG, "mSessionHandler is null");
-            }
-        }
+    public void start(Context context) {
 
-        public void associateBCAReceiver(BluetoothDevice device) {
-            Log.i(TAG, "associateBCAReceiver :"+device);
-             //Do not forward associate BCA Receiver request to state machine, if BT is not on.
-            if (isBluetoothLeOn() && mStateMachine != null) {
-                mStateMachine.sendMessage(GattBroadcastServiceStateMachine
-                        .ASSOCIATE_BCA_RECEIVER, device);
-            } else if (mSessionHandler != null) {
-                mSessionHandler.sendMessage(
-                        mSessionHandler.obtainMessage(NOTIFY_CB_ASSOCIATE_BCA_RECEIVER,
-                        ASSOCIATE_BCA_RECEIVER_FAILED, HANDLER_ARG_NOT_USED, device));
-            } else {
-                Log.i(TAG, "mSessionHandler is null");
-            }
-        }
-
-    };
-
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        Log.i(TAG, "onCreate");
-
-        mContext = getApplicationContext();
-        if (!initAdapter()) {
-            Log.e(TAG, "onCreate: Unexpected error");
-            stopSelf();
-            return;
-        }
-
-        mBAAudio = new BAAudio(mContext);
-        mBleScanner = new BleScanner(this, mContext);
-        mBleAdvertiser = new BleAdvertiser(this, mContext);
+        mContext = context;
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
+        mBleScanner = new BleScanner();
+        mBleAdvertiser = new BleAdvertiser();
 
         HandlerThread thread = new HandlerThread("BluetoothGattBroadcastServiceHandler");
         thread.start();
         Looper looper = thread.getLooper();
 
-        mSessionHandler = new GattBroadcastServiceMessageHandler(this, looper);
-
-        mStateMachine = new GattBroadcastServiceStateMachine(this, mContext);
-        Log.i("GattBroadcastServiceStateMachine", "make");
+        mSessionHandler = new GattBroadcastServiceMessageHandler(looper);
+        mBATService = BATService.getBATService();
+        mStateMachine = new GattBroadcastServiceStateMachine();
         mStateMachine.start();
         mReceiver = new GattBroadcastServiceReceiver();
 
-        IntentFilter filter = new IntentFilter();
-
-        filter.addAction(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
-        filter.addAction(BluetoothBATransmitter.ACTION_BAT_STATE_CHANGED);
-        filter.addAction(BluetoothBATransmitter.ACTION_BAT_ENCRYPTION_KEY_CHANGED);
-        filter.addAction(BluetoothBATransmitter.ACTION_BAT_DIV_CHANGED);
-        filter.addAction(BluetoothBATransmitter.ACTION_BAT_STREAMING_ID_CHANGED);
+        IntentFilter filter = new IntentFilter(BATService.ACTION_BAT_STATE_CHANGED);
+        filter.addAction(BATService.ACTION_BAT_ENCRYPTION_KEY_CHANGED);
+        filter.addAction(BATService.ACTION_BAT_DIV_CHANGED);
+        filter.addAction(BATService.ACTION_BAT_STREAMING_ID_CHANGED);
         filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
         filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
-        registerReceiver(mReceiver, filter);
+        filter.addAction(BATService.ACTION_BAT_BRA_ENABLE);
+        filter.addAction(BATService.ACTION_BAT_BRA_DISABLE);
+        filter.addAction(BATService.ACTION_BAT_ASSOCIATE_BCA_RECEIVER);
+        mContext.registerReceiver(mReceiver, filter);
     }
 
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        Log.i(TAG, " onStartCommand");
-        return START_NOT_STICKY;
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        Log.i(TAG, "onDestroy");
-
+    public void stop() {
+        Log.i(TAG, "Stop");
         if (mStateMachine != null) {
             mStateMachine.doQuit();
         }
 
         if (mSessionHandler != null) {
-            //Perform cleanup in Handler running on worker Thread
+            // Perform cleanup in Handler running on Worker Thread
             mSessionHandler.removeCallbacksAndMessages(null);
             Looper looper = mSessionHandler.getLooper();
             if (looper != null) {
@@ -253,46 +210,17 @@
         }
 
         if (mReceiver != null) {
-            unregisterReceiver(mReceiver);
+            mContext.unregisterReceiver(mReceiver);
         }
     }
 
-    @Override
-    public IBinder onBind(Intent intent) {
-        // Return the interface
-        return mBinder;
-    }
-
-    private boolean initAdapter() {
-        mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
-        if (mBluetoothManager == null)
-        {
-            Log.e(TAG, "mBluetoothManager is null");
-            return false;
-        }
-
-        mBluetoothAdapter = mBluetoothManager.getAdapter();
-        if (mBluetoothAdapter == null) {
-            Log.e(TAG, "mBluetoothAdapter is null");
-            return false;
-        }
-
-        boolean isBtEnabled = mBluetoothAdapter.isEnabled();
-        if (!isBtEnabled) {
-           Log.e(TAG, "bt is not enabled");
-           return false;
-        }
-
-        return true;
-    }
-
     private boolean isBluetoothLeOn() {
         if (mBluetoothAdapter != null) {
             if (mBluetoothAdapter.isLeEnabled()) {
                 Log.i(TAG, "isBluetoothLeOn: true");
                 return true;
             } else {
-                Log.i(TAG, "bluetooth le state " + mBluetoothAdapter.getLeState());
+                Log.i(TAG, "Bluetooth LE state " + mBluetoothAdapter.getLeState());
             }
         } else {
             Log.i(TAG, " mBluetoothAdapter is null");
@@ -302,12 +230,10 @@
 
 
     private final class GattBroadcastServiceMessageHandler extends Handler {
-        Context mContxt;
-        private static final String TAG = Utils.TAG + "GattBroadcastServiceMessageHandler";
+        private static final String TAG = "GattBroadcastServiceMessageHandler";
 
-        private GattBroadcastServiceMessageHandler(Context contxt, Looper looper) {
+        private GattBroadcastServiceMessageHandler(Looper looper) {
             super(looper);
-            mContxt = contxt;
             Log.i(TAG, "GattBroadcastServiceMessageHandler ");
         }
 
@@ -325,25 +251,20 @@
                 case NOTIFY_CB_ASSOCIATE_BCA_RECEIVER:
                     status = msg.arg1;
                     dev = (BluetoothDevice) msg.obj;
-                    try {
-                        if (mGattBroadcastServiceCallback != null) {
-                            mGattBroadcastServiceCallback
-                                    .onAssociatedBCAReceiver(dev, status);
-                        }
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "remote exception:  ", e);
-                    }
+                    Intent notify_on_associated_BCA_Receiver = new Intent(
+                            BATService.ACTION_BAT_ON_ASSOCIATED_BCA_RECEIVER);
+                    notify_on_associated_BCA_Receiver.putExtra(BATService.EXTRA_STATUS, status);
+                    notify_on_associated_BCA_Receiver.putExtra(BluetoothDevice.EXTRA_DEVICE, dev);
+                    mContext.sendBroadcast(notify_on_associated_BCA_Receiver,
+                            BATService.BLUETOOTH_PERM_ADMIN);
                     break;
                 case NOTIFY_CB_CONFIGURE_BRA:
                     status = msg.arg1;
-                    try {
-                        if (mGattBroadcastServiceCallback != null) {
-                            mGattBroadcastServiceCallback
-                                    .onConfiguredBroadcastReceiverAssociation(status);
-                        }
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "remote exception:  ", e);
-                    }
+                    Intent notify_configure_bra = new Intent(
+                            BATService.ACTION_BAT_BRA_STATE_CHANGED);
+                    notify_configure_bra.putExtra(BATService.EXTRA_STATUS, status);
+                    mContext.sendBroadcast(notify_configure_bra,
+                            BATService.BLUETOOTH_PERM_ADMIN);
                     break;
                 case NOTIFY_CB_ONLOST_ONFOUND_RECEIVER:
                     boolean isFound;
@@ -357,12 +278,14 @@
                     } else {
                         return;
                     }
-                    try {
-                        if (mGattBroadcastServiceCallback != null)
-                            mGattBroadcastServiceCallback.onFoundOnLostBCAReceiver(result, isFound);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "remote exception:  ", e);
-                    }
+
+                    Intent notify_onlost_onfound_receiver = new Intent(
+                            BATService.ACTION_BAT_ONFOUND_ONLOST_BCA_RECEIVER);
+                    notify_onlost_onfound_receiver.putExtra(BATService.EXTRA_SCAN_RESULT,
+                            result);
+                    notify_onlost_onfound_receiver.putExtra(BATService.EXTRA_ONFOUND, isFound);
+                    mContext.sendBroadcast(notify_onlost_onfound_receiver,
+                            BATService.BLUETOOTH_PERM_ADMIN);
                     break;
                 default:
                     break;
@@ -370,20 +293,14 @@
         }
     };
 
-    public class BleScanner {
-        private static final String TAG = Utils.TAG + "GattBroadcastService: BleScanner";
+    private class BleScanner {
+        private static final String TAG = "GattBroadcastService: BleScanner";
         private BluetoothLeScanner mScanner;
         private ScanCallback mCallback;
-        private GattBroadcastService mService;
-        private Context mContext;
-        private BluetoothGatt mBluetoothGatt = null;
-        private String mOwnAddress = null;
         private boolean mScanning = false;
 
-        private BleScanner(GattBroadcastService svc, Context context) {
-            Log.i(TAG, "BleScanner ");
-            mService = svc;
-            mContext = context;
+        private BleScanner() {
+            Log.d(TAG, "BleScanner ");
             mCallback = new GattBroadcastReceiverScanCallback();
             mScanner = mBluetoothAdapter.getBluetoothLeScanner();
         }
@@ -397,8 +314,8 @@
                         List<ScanFilter> filters = new ArrayList<ScanFilter>();
                         ScanSettings.Builder settingBuilder = new ScanSettings.Builder();
                         filters.add(new ScanFilter.Builder()
-                                .setServiceSolicitationUuid(new ParcelUuid(GattBroadcastService
-                                        .GATT_BROADCAST_SERVICE_UUID))
+                                .setServiceSolicitationUuid(new ParcelUuid(
+                                        GATT_BROADCAST_SERVICE_UUID))
                                 .build());
                         settingBuilder.setScanMode(ScanSettings.SCAN_MODE_BALANCED);
                         settingBuilder.setCallbackType(ScanSettings.CALLBACK_TYPE_FIRST_MATCH |
@@ -436,9 +353,9 @@
     }
 
 
-    public class BleAdvertiser {
+    private class BleAdvertiser {
 
-        private static final String TAG = Utils.TAG + "GattBroadcastService: BleAdvertiser";
+        private static final String TAG = "GattBroadcastService: BleAdvertiser";
         private final int DIV_LENGTH = 2;
         public static final int BRA_ENABLED_STREAMING_PAUSED_ADV_INTERVAL = 160;// 100ms
         public static final int BRA_ENABLED_STREAMING_ACTIVE_ADV_INTERVAL = 160;// 100ms
@@ -447,8 +364,6 @@
         private BluetoothLeAdvertiser mAdvertiser;
         private BluetoothGattServer mGattServer;
         private AdvertisingSetCallback mCallback;
-        private GattBroadcastService mService;
-        private Context mContext;
         private int mState;
 
         //characterstic related object
@@ -469,7 +384,8 @@
          * GATT callbacks
          */
         private final BluetoothGattServerCallback mGattCallbacks = new
-                BluetoothGattServerCallback() {
+            BluetoothGattServerCallback() {
+
             @Override
             public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
 
@@ -532,8 +448,8 @@
 
             @Override
             public void onCharacteristicReadRequest(BluetoothDevice device, int requestId,
-                                                    int offset, BluetoothGattCharacteristic
-                                                            characteristic) {
+                    int offset, BluetoothGattCharacteristic characteristic) {
+
                 if (mState == BluetoothProfile.STATE_CONNECTED) {
                     UUID uuid = characteristic.getUuid();
                     byte[] value = {0};
@@ -572,10 +488,8 @@
             }
         };
 
-        private BleAdvertiser(GattBroadcastService svc, Context context) {
+        private BleAdvertiser() {
             Log.i(TAG, "BleAdvertiser");
-            mService = svc;
-            mContext = context;
             mCallback = new GattBroadcastAdvertiseCallback();
             mAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
 
@@ -603,8 +517,7 @@
             Log.i(TAG, "startAdvertising:");
             if (isBluetoothLeOn() == false) return;
 
-            AdvertiseData data = generateAdvertiseData(GattBroadcastService
-                    .GATT_BROADCAST_SERVICE_UUID,
+            AdvertiseData data = generateAdvertiseData(GATT_BROADCAST_SERVICE_UUID,
                     getDiv());
 
             AdvertisingSetParameters.Builder parameters = new AdvertisingSetParameters.Builder();
@@ -822,9 +735,6 @@
         }
 
         private class BroadcastAddress {
-            public static final int LAP_OFFSET = 0;
-            public static final int UAP_OFFSET = 3;
-            public static final int NAP_OFFSET = 4;
             public static final int BROADCAST_ADDRESS_LENGTH = 7;
             private byte[] mAddress;
 
@@ -1018,8 +928,10 @@
                             Map<Integer, Long> mServiceRecordData = record.getServiceRecord
                                     (streamIDs[i]);
                             for (Map.Entry<Integer, Long> entry : mServiceRecordData.entrySet()) {
+
                                 Log.i(TAG, " Key< " + entry.getKey() + " >" + " value <"
                                         + entry.getValue() + ">");
+
                                 if (entry.getKey() == BluetoothBAStreamServiceRecord
                                         .BSSR_TYPE_SECURITY_ID) {
                                     long entryValue = entry.getValue().longValue();
@@ -1330,6 +1242,14 @@
                     }
                     mDevice = null;
                 }
+            } else if (action.equals(BATService.ACTION_BAT_BRA_ENABLE)) {
+                configureBroadcastReceiverAssociation(true);
+            } else if (action.equals(BATService.ACTION_BAT_BRA_DISABLE)) {
+                configureBroadcastReceiverAssociation(false);
+            } else if (action.equals(BATService.ACTION_BAT_ASSOCIATE_BCA_RECEIVER)) {
+                BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(
+                    BluetoothDevice.EXTRA_DEVICE);
+                associateBCAReceiver(device);
             } else {
                 if (action.equals(BluetoothAdapter.ACTION_BLE_STATE_CHANGED)
                     || isBluetoothLeOn()) {
@@ -1341,7 +1261,7 @@
         }
     }
 
-    public class GattBroadcastServiceStateMachine extends StateMachine {
+    class GattBroadcastServiceStateMachine extends StateMachine {
 
         public static final int INTENT = 1;
         public static final int CONFIGURE_BROADCAST_RECEIVER_ASSOCIATION = 2;
@@ -1353,14 +1273,10 @@
         private BRADisabledStreamingActive mBRADisabledStreamingActive;
         private BRAEnabledStreamingPaused mBRAEnabledStreamingPaused;
         private BRAEnabledStreamingActive mBRAEnabledStreamingActive;
-        private GattBroadcastService mService;
-        private Context mContext;
         private BluetoothAdapter mAdapter;
 
-        private GattBroadcastServiceStateMachine(GattBroadcastService svc, Context context) {
+        private GattBroadcastServiceStateMachine() {
             super("GattBroadcastServiceStateMachine");
-            mService = svc;
-            mContext = context;
             mAdapter = BluetoothAdapter.getDefaultAdapter();
 
             mBRADisabledStreamingDisabled = new BRADisabledStreamingDisabled();
@@ -1375,10 +1291,9 @@
             addState(mBRAEnabledStreamingPaused);
             addState(mBRAEnabledStreamingActive);
 
-            if ( mBAAudio.getBATState() ==
-            BluetoothBATransmitter.STATE_PLAYING) {
+            if (mBATService.getBATState() == BATService.STATE_PLAYING) {
                 setInitialState(mBRADisabledStreamingActive);
-                int div = mBAAudio.getDIV();
+                int div = mBATService.getDIV();
                 Log.d("GattBroadcastServiceStateMachine:", "div = " + div);
                 if (div != -1) {
                     mBleAdvertiser.setDiv(div);
@@ -1390,7 +1305,7 @@
                         BleAdvertiser.BRA_DISABLED_STREAMING_ACTIVE_ADV_INTERVAL);
                 }
             }
-            else if (mBAAudio.getBATState() == BluetoothBATransmitter.STATE_PAUSED)
+            else if (mBATService.getBATState() == BATService.STATE_PAUSED)
                 setInitialState(mBRADisabledStreamingPaused);
             else
                 setInitialState(mBRADisabledStreamingDisabled);
@@ -1430,36 +1345,28 @@
                         String action = intent.getAction();
                         Log.i(TAG, action);
 
-                        if (action.equals(BluetoothAdapter.ACTION_BLE_STATE_CHANGED)) {
-                            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                                    BluetoothAdapter.ERROR);
-                            int prevState = intent.getIntExtra(BluetoothAdapter
-                                    .EXTRA_PREVIOUS_STATE, BluetoothAdapter.ERROR);
-                            processBTStateChangedEvent(state, prevState);
-                        } else if (action.equals(BluetoothBATransmitter.ACTION_BAT_STATE_CHANGED)) {
-                            int state = intent.getIntExtra(BluetoothBATransmitter.EXTRA_STATE, -1);
-                            int prevState = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_PREVIOUS_STATE, -1);
+                        if (action.equals(BATService.ACTION_BAT_STATE_CHANGED)) {
+                            int state = intent.getIntExtra(BATService.EXTRA_STATE, -1);
+                            int prevState = intent.getIntExtra(
+                                    BATService.EXTRA_PREVIOUS_STATE, -1);
                             processBATStateChangedEvent(state, prevState);
-                        } else if (action.equals(BluetoothBATransmitter
-                                .ACTION_BAT_ENCRYPTION_KEY_CHANGED)) {
+                        } else if (action.equals(
+                                    BATService.ACTION_BAT_ENCRYPTION_KEY_CHANGED)) {
                             BluetoothBAEncryptionKey encKey = intent.getParcelableExtra
-                                    (BluetoothBATransmitter.EXTRA_ECNRYPTION_KEY);
+                                    (BATService.EXTRA_ECNRYPTION_KEY);
                             processBATEncryptionKeyChangedEvent(encKey);
-                        } else if (action.equals(BluetoothBATransmitter.ACTION_BAT_DIV_CHANGED)) {
-                            int div = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_DIV_VALUE, -1);
+                        } else if (action.equals(BATService.ACTION_BAT_DIV_CHANGED)) {
+                            int div = intent.getIntExtra(BATService.EXTRA_DIV_VALUE, -1);
                             processBATDivChangedEvent(div);
-                        } else if (action.equals(BluetoothBATransmitter
-                                .ACTION_BAT_STREAMING_ID_CHANGED)) {
-                            int streamingId = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_STREAM_ID, -1);
+                        } else if (action.equals(BATService.ACTION_BAT_STREAMING_ID_CHANGED)) {
+                            int streamingId = intent.getIntExtra(
+                                    BATService.EXTRA_STREAM_ID, -1);
                             processBATStreamingIdChangedEvent(streamingId);
                         }
                         break;
 
                     case CONFIGURE_BROADCAST_RECEIVER_ASSOCIATION:
-                        boolean enable = (boolean) message.obj;
+                        boolean enable = (Boolean) message.obj;
                         processConfigureBroadcastReceiverAssociation(enable);
                         break;
 
@@ -1481,19 +1388,19 @@
                     return;
                 }
                 switch (state) {
-                    case BluetoothBATransmitter.STATE_PAUSED:
-                        if (mBAAudio != null && mBleAdvertiser != null) {
+                    case BATService.STATE_PAUSED:
+                        if (mBATService != null && mBleAdvertiser != null) {
                             mBleAdvertiser.mBroadcastStreamServiceRecords
-                                .setBroadcastStreamServiceRecords(mBAAudio.getBAServiceRecord());
+                                .setBroadcastStreamServiceRecords(mBATService.getBAServiceRecord());
 
-                            processBATDivChangedEvent(mBAAudio.getDIV());
+                            processBATDivChangedEvent(mBATService.getDIV());
 
                             mBleAdvertiser.startAdvertising(false,
                                 BleAdvertiser.BRA_DISABLED_STREAMING_PAUSED_ADV_INTERVAL);
 
                             transitionTo(mBRADisabledStreamingPaused);
                         } else {
-                            Log.e(TAG, "mBAAudio: " + mBAAudio + " mBleAdvertiser: "
+                            Log.e(TAG, "mBATService: " + mBATService + " mBleAdvertiser: "
                                     + mBleAdvertiser);
                         }
                         break;
@@ -1503,22 +1410,6 @@
                 }
             }
 
-            private void processBTStateChangedEvent(int state, int prevState) {
-                Log.i(TAG, "processBTStateChangedEvent prevState " + prevState
-                        + " state: " + state);
-                if (prevState == state) {
-                    return;
-                }
-                switch (state) {
-                    case BluetoothAdapter.STATE_BLE_TURNING_OFF:
-                        stopSelf();
-                        break;
-                    default:
-                        Log.w(TAG, "state " + state + " not handled");
-                        break;
-                }
-            }
-
             private void processBATEncryptionKeyChangedEvent(BluetoothBAEncryptionKey encKey) {
                 Log.i(TAG, "processBATEncryptionKeyChangedEvent encKey:" + encKey);
                 if (encKey != null) {
@@ -1579,30 +1470,20 @@
                         String action = intent.getAction();
                         Log.i(TAG, action);
 
-                        if (action.equals(BluetoothAdapter.ACTION_BLE_STATE_CHANGED)) {
-                            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                                    BluetoothAdapter.ERROR);
-                            int prevState = intent.getIntExtra(BluetoothAdapter
-                                    .EXTRA_PREVIOUS_STATE, BluetoothAdapter.ERROR);
-                            processBTStateChangedEvent(state, prevState);
-                        } else if (action.equals(BluetoothBATransmitter.ACTION_BAT_STATE_CHANGED)) {
-                            int state = intent.getIntExtra(BluetoothBATransmitter.EXTRA_STATE, -1);
-                            int prevState = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_PREVIOUS_STATE, -1);
+                        if (action.equals(BATService.ACTION_BAT_STATE_CHANGED)) {
+                            int state = intent.getIntExtra(BATService.EXTRA_STATE, -1);
+                            int prevState = intent.getIntExtra(
+                                BATService.EXTRA_PREVIOUS_STATE, -1);
                             processBATStateChangedEvent(state, prevState);
-                        } else if (action.equals(BluetoothBATransmitter
-                                .ACTION_BAT_ENCRYPTION_KEY_CHANGED)) {
+                        } else if (action.equals(BATService.ACTION_BAT_ENCRYPTION_KEY_CHANGED)) {
                             BluetoothBAEncryptionKey encKey = intent.getParcelableExtra
-                                    (BluetoothBATransmitter.EXTRA_ECNRYPTION_KEY);
+                                    (BATService.EXTRA_ECNRYPTION_KEY);
                             processBATEncryptionKeyChangedEvent(encKey);
-                        } else if (action.equals(BluetoothBATransmitter.ACTION_BAT_DIV_CHANGED)) {
-                            int div = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_DIV_VALUE, -1);
+                        } else if (action.equals(BATService.ACTION_BAT_DIV_CHANGED)) {
+                            int div = intent.getIntExtra(BATService.EXTRA_DIV_VALUE, -1);
                             processBATDivChangedEvent(div);
-                        } else if (action.equals(BluetoothBATransmitter
-                                .ACTION_BAT_STREAMING_ID_CHANGED)) {
-                            int streamingId = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_STREAM_ID, -1);
+                        } else if (action.equals(BATService.ACTION_BAT_STREAMING_ID_CHANGED)) {
+                            int streamingId = intent.getIntExtra(BATService.EXTRA_STREAM_ID, -1);
                             processBATStreamingIdChangedEvent(streamingId);
                         }
                         break;
@@ -1628,7 +1509,7 @@
                     return;
                 }
                 switch (state) {
-                    case BluetoothBATransmitter.STATE_DISABLED:
+                    case BATService.STATE_DISABLED:
                         if (mBleAdvertiser != null) {
                             mBleAdvertiser.stopAdvertising();
                             transitionTo(mBRADisabledStreamingDisabled);
@@ -1636,7 +1517,7 @@
                             Log.e(TAG, "mBleAdvertiser is null");
                         }
                         break;
-                    case BluetoothBATransmitter.STATE_PLAYING:
+                    case BATService.STATE_PLAYING:
                         if (mBleAdvertiser != null) {
                             mBleAdvertiser.stopAdvertising();
 
@@ -1656,27 +1537,6 @@
                 }
             }
 
-            private void processBTStateChangedEvent(int state, int prevState) {
-                Log.i(TAG, "processBTStateChangedEvent prevState: " + prevState
-                        + " state: " + state);
-                if (prevState == state) {
-                    return;
-                }
-                switch (state) {
-                    case BluetoothAdapter.STATE_BLE_ON:
-                        if (mBleAdvertiser != null) {
-                            mBleAdvertiser.stopAdvertising();
-                            transitionTo(mBRADisabledStreamingDisabled);
-                        } else {
-                            Log.e(TAG, "mBleAdvertiser is null");
-                        }
-                        break;
-                    default:
-                        Log.w(TAG, "state " + state + " not handled");
-                        break;
-                }
-            }
-
             private void processBATEncryptionKeyChangedEvent(BluetoothBAEncryptionKey encKey) {
                 Log.i(TAG, "processBATEncryptionKeyChangedEvent encKey:" + encKey);
                 if (encKey != null) {
@@ -1694,7 +1554,7 @@
                 }
             }
 
-            private void processBATStreamingIdChangedEvent(int streamingId) {
+            private void processBATStreamingIdChangedEvent(long streamingId) {
                 Log.i(TAG, "processBATStreamingIdChangedEvent streamingId:" + streamingId);
                 if (streamingId != -1) {
                     mBleAdvertiser.mBroadcastStatus.setActiveStreamId((byte) streamingId);
@@ -1704,14 +1564,14 @@
             private void processConfigureBroadcastReceiverAssociation(boolean enable) {
                 Log.i(TAG, "processConfigureBroadcastReceiverAssociation enable:" + enable);
                 if (enable) {
-                    if (mBAAudio != null && mSessionHandler != null
+                    if (mBATService != null && mSessionHandler != null
                         && mBleScanner != null && mBleAdvertiser != null) {
 
                         mBleAdvertiser.stopAdvertising();
 
-                        processBATDivChangedEvent(mBAAudio.getDIV());
-                        processBATStreamingIdChangedEvent(mBAAudio.getStreamId());
-                        processBATEncryptionKeyChangedEvent(mBAAudio.getEncKey());
+                        processBATDivChangedEvent(mBATService.getDIV());
+                        processBATStreamingIdChangedEvent(mBATService.getStreamId());
+                        processBATEncryptionKeyChangedEvent(mBATService.getEncryptionKey());
 
                         mBleAdvertiser.startAdvertising(true,
                                 BleAdvertiser.BRA_ENABLED_STREAMING_PAUSED_ADV_INTERVAL);
@@ -1722,12 +1582,12 @@
 
                         mSessionHandler.sendMessage(
                                 mSessionHandler.obtainMessage(NOTIFY_CB_CONFIGURE_BRA,
-                                BRA_ENABLED_SUCESSS));
+                                BRA_ENABLED_SUCCESS));
 
                     } else {
                         Log.e(TAG, "mSessionHandler: " + mSessionHandler
-                                + " mBAAudio: " + mBAAudio + " mBleScanner: " + mBleScanner
-                                + " mBleAdvertiser: " + mBleAdvertiser);
+                                + " mBATService: " + mBATService + " mBleScanner: "
+                                + mBleScanner + " mBleAdvertiser: " + mBleAdvertiser);
                         mSessionHandler.sendMessage(
                                 mSessionHandler.obtainMessage(NOTIFY_CB_CONFIGURE_BRA,
                                 BRA_ENABLED_FAILED));
@@ -1769,36 +1629,26 @@
                         String action = intent.getAction();
                         Log.i(TAG, action);
 
-                        if (action.equals(BluetoothAdapter.ACTION_BLE_STATE_CHANGED)) {
-                            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                                    BluetoothAdapter.ERROR);
-                            int prevState = intent.getIntExtra(BluetoothAdapter
-                                    .EXTRA_PREVIOUS_STATE, BluetoothAdapter.ERROR);
-                            processBTStateChangedEvent(state, prevState);
-                        } else if (action.equals(BluetoothBATransmitter.ACTION_BAT_STATE_CHANGED)) {
-                            int state = intent.getIntExtra(BluetoothBATransmitter.EXTRA_STATE, -1);
-                            int prevState = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_PREVIOUS_STATE, -1);
+                        if (action.equals(BATService.ACTION_BAT_STATE_CHANGED)) {
+                            int state = intent.getIntExtra(BATService.EXTRA_STATE, -1);
+                            int prevState = intent.getIntExtra(
+                                    BATService.EXTRA_PREVIOUS_STATE, -1);
                             processBATStateChangedEvent(state, prevState);
-                        } else if (action.equals(BluetoothBATransmitter
-                                .ACTION_BAT_ENCRYPTION_KEY_CHANGED)) {
+                        } else if (action.equals(BATService.ACTION_BAT_ENCRYPTION_KEY_CHANGED)) {
                             BluetoothBAEncryptionKey encKey = intent.getParcelableExtra
-                                    (BluetoothBATransmitter.EXTRA_ECNRYPTION_KEY);
+                                    (BATService.EXTRA_ECNRYPTION_KEY);
                             processBATEncryptionKeyChangedEvent(encKey);
-                        } else if (action.equals(BluetoothBATransmitter.ACTION_BAT_DIV_CHANGED)) {
-                            int div = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_DIV_VALUE, -1);
+                        } else if (action.equals(BATService.ACTION_BAT_DIV_CHANGED)) {
+                            int div = intent.getIntExtra(BATService.EXTRA_DIV_VALUE, -1);
                             processBATDivChangedEvent(div);
-                        } else if (action.equals(BluetoothBATransmitter
-                                .ACTION_BAT_STREAMING_ID_CHANGED)) {
-                            int streamingId = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_STREAM_ID, -1);
+                        } else if (action.equals(BATService.ACTION_BAT_STREAMING_ID_CHANGED)) {
+                            int streamingId = intent.getIntExtra(BATService.EXTRA_STREAM_ID, -1);
                             processBATStreamingIdChangedEvent(streamingId);
                         }
                         break;
 
                     case CONFIGURE_BROADCAST_RECEIVER_ASSOCIATION:
-                        boolean enable = (boolean) message.obj;
+                        boolean enable = (Boolean) message.obj;
                         processConfigureBroadcastReceiverAssociation(enable);
                         break;
 
@@ -1820,7 +1670,7 @@
                     return;
                 }
                 switch (state) {
-                    case BluetoothBATransmitter.STATE_DISABLED:
+                    case BATService.STATE_DISABLED:
                         if (mBleAdvertiser != null) {
                             mBleAdvertiser.stopAdvertising();
                             transitionTo(mBRADisabledStreamingDisabled);
@@ -1828,7 +1678,7 @@
                             Log.e(TAG, "mBleAdvertiser is null");
                         }
                         break;
-                    case BluetoothBATransmitter.STATE_PAUSED:
+                    case BATService.STATE_PAUSED:
                         if (mBleAdvertiser != null) {
                             mBleAdvertiser.stopAdvertising();
 
@@ -1848,27 +1698,6 @@
                 }
             }
 
-            private void processBTStateChangedEvent(int state, int prevState) {
-                Log.i(TAG, "processBTStateChangedEvent prevState: " + prevState
-                        + " state: " + state);
-                if (prevState == state) {
-                    return;
-                }
-                switch (state) {
-                    case BluetoothAdapter.STATE_BLE_ON:
-                        if (mBleAdvertiser != null) {
-                            mBleAdvertiser.stopAdvertising();
-                            transitionTo(mBRADisabledStreamingDisabled);
-                        } else {
-                            Log.i(TAG, "mBleAdvertiser is null");
-                        }
-                        break;
-                    default:
-                        Log.w(TAG, "state " + state + " not handled");;
-                        break;
-                }
-            }
-
             private void processBATEncryptionKeyChangedEvent(BluetoothBAEncryptionKey encKey) {
                 Log.i(TAG, "processBATEncryptionKeyChangedEvent encKey:" + encKey);
                 if (encKey != null) {
@@ -1886,7 +1715,7 @@
                 }
             }
 
-            private void processBATStreamingIdChangedEvent(int streamingId) {
+            private void processBATStreamingIdChangedEvent(long streamingId) {
                 Log.i(TAG, "processBATStreamingIdChangedEvent streamingId:" + streamingId);
                 if (streamingId != -1) {
                     mBleAdvertiser.mBroadcastStatus.setActiveStreamId((byte) streamingId);
@@ -1896,14 +1725,14 @@
             private void processConfigureBroadcastReceiverAssociation(boolean enable) {
                 Log.i(TAG, "processConfigureBroadcastReceiverAssociation enable:" + enable);
                 if (enable) {
-                    if (mBAAudio != null && mSessionHandler != null
+                    if (mBATService != null && mSessionHandler != null
                         && mBleScanner != null && mBleAdvertiser != null) {
 
                         mBleAdvertiser.stopAdvertising();
 
-                        processBATDivChangedEvent(mBAAudio.getDIV());
-                        processBATStreamingIdChangedEvent(mBAAudio.getStreamId());
-                        processBATEncryptionKeyChangedEvent(mBAAudio.getEncKey());
+                        processBATDivChangedEvent(mBATService.getDIV());
+                        processBATStreamingIdChangedEvent(mBATService.getStreamId());
+                        processBATEncryptionKeyChangedEvent(mBATService.getEncryptionKey());
 
                         mBleAdvertiser.startAdvertising(true,
                                 BleAdvertiser.BRA_ENABLED_STREAMING_ACTIVE_ADV_INTERVAL);
@@ -1914,12 +1743,12 @@
 
                         mSessionHandler.sendMessage(
                                 mSessionHandler.obtainMessage(NOTIFY_CB_CONFIGURE_BRA,
-                                BRA_ENABLED_SUCESSS));
+                                BRA_ENABLED_SUCCESS));
 
                     } else {
                         Log.e(TAG, "mSessionHandler: " + mSessionHandler
-                                + " mBAAudio: " + mBAAudio + " mBleScanner: " + mBleScanner
-                                + " mBleAdvertiser: " + mBleAdvertiser);
+                                + " mBATService: " + mBATService + " mBleScanner: "
+                                + mBleScanner + " mBleAdvertiser: " + mBleAdvertiser);
                         mSessionHandler.sendMessage(
                                 mSessionHandler.obtainMessage(NOTIFY_CB_CONFIGURE_BRA,
                                 BRA_ENABLED_FAILED));
@@ -1959,30 +1788,20 @@
                         String action = intent.getAction();
                         Log.i(TAG, action);
 
-                        if (action.equals(BluetoothAdapter.ACTION_BLE_STATE_CHANGED)) {
-                            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                                    BluetoothAdapter.ERROR);
-                            int prevState = intent.getIntExtra(BluetoothAdapter
-                                    .EXTRA_PREVIOUS_STATE, BluetoothAdapter.ERROR);
-                            processBTStateChangedEvent(state, prevState);
-                        } else if (action.equals(BluetoothBATransmitter.ACTION_BAT_STATE_CHANGED)) {
-                            int state = intent.getIntExtra(BluetoothBATransmitter.EXTRA_STATE, -1);
-                            int prevState = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_PREVIOUS_STATE, -1);
+                        if (action.equals(BATService.ACTION_BAT_STATE_CHANGED)) {
+                            int state = intent.getIntExtra(BATService.EXTRA_STATE, -1);
+                            int prevState = intent.getIntExtra(
+                                    BATService.EXTRA_PREVIOUS_STATE, -1);
                             processBATStateChangedEvent(state, prevState);
-                        } else if (action.equals(BluetoothBATransmitter
-                                .ACTION_BAT_ENCRYPTION_KEY_CHANGED)) {
+                        } else if (action.equals(BATService.ACTION_BAT_ENCRYPTION_KEY_CHANGED)) {
                             BluetoothBAEncryptionKey encKey = intent.getParcelableExtra
-                                    (BluetoothBATransmitter.EXTRA_ECNRYPTION_KEY);
+                                    (BATService.EXTRA_ECNRYPTION_KEY);
                             processBATEncryptionKeyChangedEvent(encKey);
-                        } else if (action.equals(BluetoothBATransmitter.ACTION_BAT_DIV_CHANGED)) {
-                            int div = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_DIV_VALUE, -1);
+                        } else if (action.equals(BATService.ACTION_BAT_DIV_CHANGED)) {
+                            int div = intent.getIntExtra(BATService.EXTRA_DIV_VALUE, -1);
                             processBATDivChangedEvent(div);
-                        } else if (action.equals(BluetoothBATransmitter
-                                .ACTION_BAT_STREAMING_ID_CHANGED)) {
-                            int streamingId = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_STREAM_ID, -1);
+                        } else if (action.equals(BATService.ACTION_BAT_STREAMING_ID_CHANGED)) {
+                            int streamingId = intent.getIntExtra(BATService.EXTRA_STREAM_ID, -1);
                             processBATStreamingIdChangedEvent(streamingId);
                         }
                         break;
@@ -2010,7 +1829,7 @@
                     return;
                 }
                 switch (state) {
-                    case BluetoothBATransmitter.STATE_DISABLED:
+                    case BATService.STATE_DISABLED:
                         if (mBleScanner != null) {
                             mBleScanner.discoverBroadcastAudioReceiver(false);
                         } else {
@@ -2026,7 +1845,7 @@
 
                         transitionTo(mBRADisabledStreamingDisabled);
                         break;
-                    case BluetoothBATransmitter.STATE_PLAYING:
+                    case BATService.STATE_PLAYING:
                         transitionTo(mBRAEnabledStreamingActive);
                         break;
                     default:
@@ -2035,35 +1854,6 @@
                 }
             }
 
-            private void processBTStateChangedEvent(int state, int prevState) {
-                Log.i(TAG, "processBTStateChangedEvent prevState: " + prevState
-                        + " state: " + state);
-                if (prevState == state) {
-                    return;
-                }
-                switch (state) {
-                    case BluetoothAdapter.STATE_BLE_ON:
-                        if (mBleScanner != null) {
-                            mBleScanner.discoverBroadcastAudioReceiver(false);
-                        } else {
-                            Log.i(TAG, "mBleScanner is null");
-                        }
-
-                        if (mBleAdvertiser != null) {
-                            mBleAdvertiser.closeServer();
-                            mBleAdvertiser.stopAdvertising();
-                        } else {
-                            Log.i(TAG, "mBleAdvertiser is null");
-                        }
-
-                        transitionTo(mBRADisabledStreamingDisabled);
-                        break;
-                    default:
-                        Log.w(TAG, "state " + state + " not handled");
-                        break;
-                }
-            }
-
             private void processBATEncryptionKeyChangedEvent(BluetoothBAEncryptionKey encKey) {
                 Log.i(TAG, "processBATEncryptionKeyChangedEvent encKey:" + encKey);
                 if (encKey != null) {
@@ -2081,7 +1871,7 @@
                 }
             }
 
-            private void processBATStreamingIdChangedEvent(int streamingId) {
+            private void processBATStreamingIdChangedEvent(long streamingId) {
                 Log.i(TAG, "processBATStreamingIdChangedEvent streamingId:" + streamingId);
                 if (streamingId != -1) {
                     mBleAdvertiser.mBroadcastStatus.setActiveStreamId((byte) streamingId);
@@ -2093,7 +1883,7 @@
                 if (enable) {
                     Log.i(TAG, "Unexpected, Ignoring BRA enable");
                 } else {
-                    int status = BRA_DISABLED_SUCESSS;
+                    int status = BRA_DISABLED_SUCCESS;
                     if (mBleScanner != null) {
                         mBleScanner.discoverBroadcastAudioReceiver(false);
                     } else {
@@ -2156,30 +1946,20 @@
                         String action = intent.getAction();
                         Log.i(TAG, action);
 
-                        if (action.equals(BluetoothAdapter.ACTION_BLE_STATE_CHANGED)) {
-                            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                                    BluetoothAdapter.ERROR);
-                            int prevState = intent.getIntExtra(BluetoothAdapter
-                                    .EXTRA_PREVIOUS_STATE, BluetoothAdapter.ERROR);
-                            processBTStateChangedEvent(state, prevState);
-                        } else if (action.equals(BluetoothBATransmitter.ACTION_BAT_STATE_CHANGED)) {
-                            int state = intent.getIntExtra(BluetoothBATransmitter.EXTRA_STATE, -1);
-                            int prevState = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_PREVIOUS_STATE, -1);
+                        if (action.equals(BATService.ACTION_BAT_STATE_CHANGED)) {
+                            int state = intent.getIntExtra(BATService.EXTRA_STATE, -1);
+                            int prevState = intent.getIntExtra(
+                                    BATService.EXTRA_PREVIOUS_STATE, -1);
                             processBATStateChangedEvent(state, prevState);
-                        } else if (action.equals(BluetoothBATransmitter
-                                .ACTION_BAT_ENCRYPTION_KEY_CHANGED)) {
+                        } else if (action.equals(BATService.ACTION_BAT_ENCRYPTION_KEY_CHANGED)) {
                             BluetoothBAEncryptionKey encKey = intent.getParcelableExtra
-                                    (BluetoothBATransmitter.EXTRA_ECNRYPTION_KEY);
+                                    (BATService.EXTRA_ECNRYPTION_KEY);
                             processBATEncryptionKeyChangedEvent(encKey);
-                        } else if (action.equals(BluetoothBATransmitter.ACTION_BAT_DIV_CHANGED)) {
-                            int div = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_DIV_VALUE, -1);
+                        } else if (action.equals(BATService.ACTION_BAT_DIV_CHANGED)) {
+                            int div = intent.getIntExtra(BATService.EXTRA_DIV_VALUE, -1);
                             processBATDivChangedEvent(div);
-                        } else if (action.equals(BluetoothBATransmitter
-                                .ACTION_BAT_STREAMING_ID_CHANGED)) {
-                            int streamingId = intent.getIntExtra(BluetoothBATransmitter
-                                    .EXTRA_STREAM_ID, -1);
+                        } else if (action.equals(BATService.ACTION_BAT_STREAMING_ID_CHANGED)) {
+                            int streamingId = intent.getIntExtra(BATService.EXTRA_STREAM_ID, -1);
                             processBATStreamingIdChangedEvent(streamingId);
                         }
                         break;
@@ -2205,7 +1985,7 @@
                     return;
                 }
                 switch (state) {
-                    case BluetoothBATransmitter.STATE_DISABLED:
+                    case BATService.STATE_DISABLED:
                         if (mBleScanner != null) {
                             mBleScanner.discoverBroadcastAudioReceiver(false);
                         } else {
@@ -2221,7 +2001,7 @@
 
                         transitionTo(mBRADisabledStreamingDisabled);
                         break;
-                    case BluetoothBATransmitter.STATE_PAUSED:
+                    case BATService.STATE_PAUSED:
                         transitionTo(mBRAEnabledStreamingPaused);
                         break;
                     default:
@@ -2230,35 +2010,6 @@
                 }
             }
 
-            private void processBTStateChangedEvent(int state, int prevState) {
-                Log.i(TAG, "processBTStateChangedEvent prevState: " + prevState
-                        + " state: " + state);
-                if (prevState == state) {
-                    return;
-                }
-                switch (state) {
-                    case BluetoothAdapter.STATE_BLE_ON:
-                        if (mBleScanner != null) {
-                            mBleScanner.discoverBroadcastAudioReceiver(false);
-                        } else {
-                            Log.i(TAG, "mBleScanner is null");
-                        }
-
-                        if (mBleAdvertiser != null) {
-                            mBleAdvertiser.closeServer();
-                            mBleAdvertiser.stopAdvertising();
-                        } else {
-                            Log.i(TAG, "mBleAdvertiser is null");
-                        }
-
-                        transitionTo(mBRADisabledStreamingDisabled);
-                        break;
-                    default:
-                        Log.w(TAG, "state " + state + " not handled");
-                        break;
-                }
-            }
-
             private void processBATEncryptionKeyChangedEvent(BluetoothBAEncryptionKey encKey) {
                 Log.i(TAG, "processBATEncryptionKeyChangedEvent encKey:" + encKey);
                 if (encKey != null) {
@@ -2276,7 +2027,7 @@
                 }
             }
 
-            private void processBATStreamingIdChangedEvent(int streamingId) {
+            private void processBATStreamingIdChangedEvent(long streamingId) {
                 Log.i(TAG, "processBATStreamingIdChangedEvent streamingId:" + streamingId);
                 if (streamingId != -1) {
                     mBleAdvertiser.mBroadcastStatus.setActiveStreamId((byte) streamingId);
@@ -2288,7 +2039,7 @@
                 if (enable) {
                     Log.i(TAG, "Unexpected, Ignoring BRA enable");
                 } else {
-                    int status = BRA_DISABLED_SUCESSS;
+                    int status = BRA_DISABLED_SUCCESS;
                     if (mBleScanner != null) {
                         mBleScanner.discoverBroadcastAudioReceiver(false);
                     } else {
@@ -2315,7 +2066,6 @@
                     } else {
                         Log.e(TAG, "mSessionHandler is null");
                     }
-
                 }
             }
 
@@ -2323,7 +2073,6 @@
                 Log.i(TAG, "processAssociateBCAReceiver BD address:" + device.getAddress());
                 mBleAdvertiser.connectDevice(device);
             }
-
         }
     }
-}
+}
\ No newline at end of file