Merge dbfdf08be44659ad9d3f90085c59b8314361110a on remote branch
Change-Id: I21bb018f97b8fb2c6d23deaf341532e8d6717263
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/jni/com_android_bluetooth_btservice_vendor.cpp b/packages_apps_bluetooth_ext/jni/com_android_bluetooth_btservice_vendor.cpp
index 0a05b7d..f3acfc5 100644
--- a/packages_apps_bluetooth_ext/jni/com_android_bluetooth_btservice_vendor.cpp
+++ b/packages_apps_bluetooth_ext/jni/com_android_bluetooth_btservice_vendor.cpp
@@ -65,6 +65,7 @@
static jmethodID method_onBredrCleanup;
static jmethodID method_iotDeviceBroadcast;
+static jmethodID method_bqrDeliver;
static jmethodID method_devicePropertyChangedCallback;
static jmethodID method_adapterPropertyChangedCallback;
static jmethodID method_ssrCleanupCallback;
@@ -159,6 +160,34 @@
(jint)glitch_count);
}
+static void bqr_delivery_callback(RawAddress* bd_addr, uint8_t lmp_ver, uint16_t lmp_subver,
+ uint16_t manufacturer_id, std::vector<uint8_t> bqr_raw_data) {
+ ALOGI("%s", __func__);
+ CallbackEnv sCallbackEnv(__func__);
+ if (!sCallbackEnv.valid()) return;
+
+ ScopedLocalRef<jbyteArray> addr(
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
+ if (!addr.get()) {
+ ALOGE("Error while allocation byte array for addr in %s", __func__);
+ return;
+ }
+ sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
+ (jbyte*)bd_addr->address);
+
+ ScopedLocalRef<jbyteArray> raw_data(
+ sCallbackEnv.get(), sCallbackEnv->NewByteArray(bqr_raw_data.size()));
+ if (!raw_data.get()) {
+ ALOGE("Error while allocation byte array for bqr raw data in %s", __func__);
+ return;
+ }
+ sCallbackEnv->SetByteArrayRegion(raw_data.get(), 0, bqr_raw_data.size(),
+ (jbyte*)bqr_raw_data.data());
+
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_bqrDeliver, addr.get(),
+ (jint)lmp_ver, (jint)lmp_subver, (jint)manufacturer_id, raw_data.get());
+}
+
static void adapter_vendor_properties_callback(bt_status_t status,
int num_properties,
bt_vendor_property_t *properties) {
@@ -255,6 +284,7 @@
sizeof(sBluetoothVendorCallbacks),
bredr_cleanup_callback,
iot_device_broadcast_callback,
+ bqr_delivery_callback,
remote_device_properties_callback,
NULL,
adapter_vendor_properties_callback,
@@ -265,6 +295,7 @@
method_onBredrCleanup = env->GetMethodID(clazz, "onBredrCleanup", "(Z)V");
method_iotDeviceBroadcast = env->GetMethodID(clazz, "iotDeviceBroadcast", "([BIIIIIIIIII)V");
+ method_bqrDeliver = env->GetMethodID(clazz, "bqrDeliver", "([BIII[B)V");
method_devicePropertyChangedCallback = env->GetMethodID(
clazz, "devicePropertyChangedCallback", "([B[I[[B)V");
method_adapterPropertyChangedCallback = env->GetMethodID(
diff --git a/packages_apps_bluetooth_ext/src/avrcp/AddressedMediaPlayer_ext.java b/packages_apps_bluetooth_ext/src/avrcp/AddressedMediaPlayer_ext.java
index a650069..4dd8e2e 100644
--- a/packages_apps_bluetooth_ext/src/avrcp/AddressedMediaPlayer_ext.java
+++ b/packages_apps_bluetooth_ext/src/avrcp/AddressedMediaPlayer_ext.java
@@ -506,10 +506,11 @@
break;
case AvrcpConstants_ext.ATTRID_COVER_ART:
- if (mAvrcp != null) {
+ if (mAvrcp != null && mAvrcp.isCoverArtFeatureSupported(bdaddr)) {
attrValue = mAvrcp.getImgHandleFromTitle(bdaddr,
desc.getTitle().toString());
} else {
+ attrValue = null;
if (DEBUG) Log.d(TAG, " mAvrcp null ");
}
break;
diff --git a/packages_apps_bluetooth_ext/src/avrcp/Avrcp_ext.java b/packages_apps_bluetooth_ext/src/avrcp/Avrcp_ext.java
index 4bdfea4..bef8fa9 100644
--- a/packages_apps_bluetooth_ext/src/avrcp/Avrcp_ext.java
+++ b/packages_apps_bluetooth_ext/src/avrcp/Avrcp_ext.java
@@ -168,6 +168,7 @@
private boolean avrcp_playstatus_blacklist = false;
private static final String [] BlacklistDeviceAddrToMediaAttr = {"00:17:53"/*Toyota Etios*/};
private boolean ignore_play;
+ private BluetoothDevice disconnectedActiveDevice;
private byte changePathFolderType;
private FolderItemsRsp_ext saveRspObj;
private int changePathDepth;
@@ -177,6 +178,8 @@
private boolean isShoActive = false;
private boolean twsShoEnabled = false;
+ byte[] dummyaddr = {(byte)0xFA, (byte)0xCE, (byte)0xFA,
+ (byte)0xCE, (byte)0xFA, (byte)0xCE};
private static final String playerStateUpdateBlackListedAddr[] = {
"BC:30:7E", //bc-30-7e-5e-f6-27, Name: Porsche BT 0310; bc-30-7e-8c-22-cb, Name: Audi MMI 1193
"00:1E:43", //00-1e-43-14-f0-68, Name: Audi MMI 4365
@@ -197,7 +200,8 @@
public static final int BTRC_FEAT_METADATA = 0x01;
public static final int BTRC_FEAT_ABSOLUTE_VOLUME = 0x02;
public static final int BTRC_FEAT_BROWSE = 0x04;
- public static final int BTRC_FEAT_AVRC_UI_UPDATE = 0x08;
+ public static final int BTRC_FEAT_COVER_ART = 0x08;
+ public static final int BTRC_FEAT_AVRC_UI_UPDATE = 0x10;
/* AVRC response codes, from avrc_defs */
private static final int AVRC_RSP_NOT_IMPL = 8;
@@ -238,6 +242,7 @@
private final static int MESSAGE_UPDATE_ABS_VOLUME_STATUS = 31;
private static final int MSG_PLAY_STATUS_CMD_TIMEOUT = 33;
private final static int MESSAGE_START_SHO = 34;
+ private static final int MSG_SET_ACTIVE_DEVICE = 35;
private static final int STACK_CLEANUP = 0;
private static final int APP_CLEANUP = 1;
@@ -363,7 +368,7 @@
private int mBlackListVolume;
private int mLastPassthroughcmd;
private int mReportedPlayerID;
-
+ private boolean mTwsPairDisconnected;
public DeviceDependentFeature(Context context) {
mContext = context;
mCurrentDevice = null;
@@ -406,6 +411,7 @@
mLastRspPlayStatus = -1;
mLastPassthroughcmd = KeyEvent.KEYCODE_UNKNOWN;
mReportedPlayerID = NO_PLAYER_ID;
+ mTwsPairDisconnected = false;
}
};
DeviceDependentFeature[] deviceFeatures;
@@ -413,6 +419,7 @@
private static class SHOQueue {
static BluetoothDevice device;
static boolean PlayReq;
+ static boolean isRetry;
}
static {
@@ -602,6 +609,7 @@
changePathDepth = 0;
changePathFolderType = 0;
changePathDirection = 0;
+ disconnectedActiveDevice = null;
Avrcp_extVolumeManager();
Log.v(TAG, "Exit start");
}
@@ -669,6 +677,7 @@
changePathDepth = 0;
changePathFolderType = 0;
changePathDirection = 0;
+ disconnectedActiveDevice = null;
Log.d(TAG, "Exit doQuit");
}
@@ -689,6 +698,30 @@
Log.d(TAG, "Exit cleanup()");
}
+ public boolean isCoverArtFeatureSupported(byte[] bdaddr) {
+ Log.w(TAG, "isCoverArtFeatureSupported");
+ String address = Utils.getAddressStringFromByte((byte[]) bdaddr);
+ BluetoothDevice device = mAdapter.getRemoteDevice(address);
+ if (device == null)
+ return false;
+ MediaPlayerInfo_ext player = mMediaPlayerInfoList.getOrDefault(mCurrAddrPlayerID, null);
+ int index = getIndexForDevice(device);
+ if ((index == INVALID_DEVICE_INDEX) || (player == null))
+ return false;
+
+ short[] featureBits = player.getFeatureBitMask();
+ boolean playerSupportsCA = false;
+ for (int i = 0; i < featureBits.length; i++) {
+ if (featureBits[i] == AvrcpConstants_ext.AVRC_PF_COVER_ART_BIT_NO) {
+ playerSupportsCA = true;
+ break;
+ }
+ }
+ boolean peerSupprtsCA = ((deviceFeatures[index].mFeatures & BTRC_FEAT_COVER_ART) != 0);
+ Log.w(TAG, "playersupportCA " + playerSupportsCA + " peersupportCA " + peerSupprtsCA);
+ return (peerSupprtsCA && playerSupportsCA);
+ }
+
private class AudioManagerPlaybackListener extends AudioManager.AudioPlaybackCallback {
@Override
public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) {
@@ -807,11 +840,11 @@
mAudioManager.avrcpSupportsAbsoluteVolume(device.getAddress(),
isAbsoluteVolumeSupported(deviceIndex));
if (mAbsVolThreshold > 0 && mAbsVolThreshold < mAudioStreamMax &&
- vol > mAbsVolThreshold) {
- if (DEBUG) Log.v(TAG, "remote inital volume too high " + vol + ">" +
- mAbsVolThreshold);
- vol = mAbsVolThreshold;
- notifyVolumeChanged(vol, false);
+ vol > mAbsVolThreshold) {
+ if (DEBUG) Log.v(TAG, "remote inital volume too high " + vol + ">" +
+ mAbsVolThreshold);
+ vol = mAbsVolThreshold;
+ notifyVolumeChanged(vol, false);
}
if (vol >= 0) {
int volume = convertToAvrcpVolume(vol);
@@ -1092,15 +1125,18 @@
Log.e(TAG,"invalid index for device");
break;
}
+ byte absVol = (byte) ((byte) msg.arg1 & 0x7f); // discard MSB as it is RFD
if (DEBUG) Log.v(TAG, "MSG_NATIVE_REQ_VOLUME_CHANGE addr: " + address);
if (((!(deviceFeatures[deviceIndex].isActiveDevice)) &&
(deviceFeatures[deviceIndex].mInitialRemoteVolume != -1)) ||
(!deviceFeatures[deviceIndex].isAbsoluteVolumeSupportingDevice)) {
+ if (deviceFeatures[deviceIndex].isAbsoluteVolumeSupportingDevice) {
+ deviceFeatures[deviceIndex].mRemoteVolume = absVol;
+ }
if (DEBUG) Log.v(TAG, "MSG_NATIVE_REQ_VOLUME_CHANGE ignored");
break;
}
- byte absVol = (byte) ((byte) msg.arg1 & 0x7f); // discard MSB as it is RFD
int absolutevol = absVol;
if (DEBUG)
Log.v(TAG, "MSG_NATIVE_REQ_VOLUME_CHANGE: volume=" + absVol + " ctype="
@@ -1137,6 +1173,12 @@
if (msg.arg2 == AVRC_RSP_ACCEPT || msg.arg2 == AVRC_RSP_REJ) {
if ((deviceFeatures[deviceIndex].mVolCmdAdjustInProgress == false) &&
(deviceFeatures[deviceIndex].mVolCmdSetInProgress == false)) {
+ if (deviceFeatures[deviceIndex].mCurrentDevice.isTwsPlusDevice()) {
+ Log.e(TAG,"Store volume for TWS+ pair for volume relays");
+ deviceFeatures[deviceIndex].mRemoteVolume = absVol;
+ deviceFeatures[deviceIndex].mLocalVolume = convertToAudioStreamVolume(absVol);
+ break;
+ }
Log.e(TAG, "Unsolicited response, ignored");
break;
}
@@ -1156,11 +1198,19 @@
if (i != deviceIndex && deviceFeatures[i].mCurrentDevice != null &&
deviceFeatures[i].mInitialRemoteVolume != -1 &&
isTwsPlusPair(conn_dev, device)) {
- Log.v(TAG,"volume already set for tws pair");
- deviceFeatures[deviceIndex].mInitialRemoteVolume = absVol;
- deviceFeatures[deviceIndex].mRemoteVolume = absVol;
- deviceFeatures[deviceIndex].mLocalVolume = convertToAudioStreamVolume(absVol);
- break;
+ Log.v(TAG,"TWS+ pair found at index " + i +
+ "mTwsPairDisconnected = " + deviceFeatures[i].mTwsPairDisconnected);
+ if (deviceFeatures[i].mTwsPairDisconnected) {
+ Log.v(TAG,"TWS+ pair was disconnected earlier");
+ Log.v(TAG,"TWS+ store this volume");
+ deviceFeatures[i].mTwsPairDisconnected = false;
+ } else {
+ Log.v(TAG,"volume already set for tws pair");
+ deviceFeatures[deviceIndex].mInitialRemoteVolume = absVol;
+ deviceFeatures[deviceIndex].mRemoteVolume = absVol;
+ deviceFeatures[deviceIndex].mLocalVolume = convertToAudioStreamVolume(absVol);
+ break;
+ }
}
}
}
@@ -1389,7 +1439,7 @@
Log.e(TAG, "1: SHO complete");
}
- if(mHandler.hasMessages(MESSAGE_START_SHO)) {
+ if(mHandler.hasMessages(MESSAGE_START_SHO) && (!SHOQueue.isRetry)) {
mHandler.removeMessages(MESSAGE_START_SHO);
triggerSHO(SHOQueue.device, SHOQueue.PlayReq, false);
}
@@ -1591,7 +1641,7 @@
synchronized (Avrcp_ext.this) {
isShoActive = false;
Log.d(TAG, "3: SHO complete");
- if (mHandler.hasMessages(MESSAGE_START_SHO)) {
+ if (mHandler.hasMessages(MESSAGE_START_SHO) && (!SHOQueue.isRetry)) {
mHandler.removeMessages(MESSAGE_START_SHO);
triggerSHO(SHOQueue.device, SHOQueue.PlayReq, false);
}
@@ -1600,6 +1650,114 @@
}
break;
+ case MSG_SET_ACTIVE_DEVICE:
+ boolean tws_switch = false;
+ Log.d(TAG, "MSG_SET_ACTIVE_DEVICE");
+ BluetoothDevice bt_device = (BluetoothDevice) msg.obj;
+ if (bt_device == null) {
+ for (int i = 0; i < maxAvrcpConnections; i++) {
+ deviceFeatures[i].isActiveDevice = false;
+ }
+ break;
+ }
+ if (bt_device != null && bt_device.isTwsPlusDevice()) {
+ for (int i = 0; i < maxAvrcpConnections; i++) {
+ if (deviceFeatures[i].mCurrentDevice != null &&
+ deviceFeatures[i].isActiveDevice &&
+ deviceFeatures[i].mCurrentDevice.isTwsPlusDevice()) {
+ tws_switch = true;
+ }
+ }
+ }
+ deviceIndex = getIndexForDevice(bt_device);
+ if (deviceIndex == INVALID_DEVICE_INDEX) {
+ Log.e(TAG,"Invalid device index for setActiveDevice");
+ for (int i = 0; i < maxAvrcpConnections; i++) {
+ deviceFeatures[i].isActiveDevice = false;
+ }
+ break;
+ }
+ deviceFeatures[deviceIndex].isActiveDevice = true;
+
+ Log.w(TAG, "Active device Calling SetBrowsePackage for " + mCachedBrowsePlayer);
+ if (mCachedBrowsePlayer != null && is_player_updated_for_browse == false) {
+ SetBrowsePackage(mCachedBrowsePlayer);
+ }
+
+ if (deviceFeatures[deviceIndex].mCurrentDevice.isTwsPlusDevice() &&
+ updateAbsVolume == true) {
+ Log.d(TAG,"setting absVolume flag for TWS+ device");
+ mAudioManager.avrcpSupportsAbsoluteVolume(bt_device.getAddress(),true);
+ AdapterService mAdapterService = AdapterService.getAdapterService();
+ BluetoothDevice peer_device = mAdapterService.
+ getTwsPlusPeerDevice(deviceFeatures[deviceIndex].mCurrentDevice);
+ if (peer_device != null &&
+ getIndexForDevice(peer_device) == INVALID_DEVICE_INDEX) {
+ Log.d(TAG,"Other TWS+ earbud not connected, reset updateAbsVolume flag");
+ updateAbsVolume = false;
+ }
+ }
+ if (bt_device.isTwsPlusDevice() && !tws_switch) {
+ Log.d(TAG,"Restting mTwsPairDisconnected at index " + deviceIndex);
+ deviceFeatures[deviceIndex].mTwsPairDisconnected = false;
+ }
+ if (maxAvrcpConnections > 1) {
+ for (int i = 0; i < maxAvrcpConnections; i++) {
+ if (deviceIndex != i && deviceFeatures[i].mCurrentDevice != null &&
+ deviceFeatures[i].mCurrentDevice.isTwsPlusDevice() &&
+ isTwsPlusPair(deviceFeatures[i].mCurrentDevice, bt_device)) {
+ Log.d(TAG,"TWS+ pair connected, keep both devices active");
+ deviceFeatures[i].isActiveDevice = true;
+ if (updateAbsVolume == true) {
+ Log.d(TAG,"Setting absVolume flag to TWS+ pair");
+ mAudioManager.avrcpSupportsAbsoluteVolume(
+ bt_device.getAddress(), true);
+ updateAbsVolume = false;
+ }
+ } else {
+ if (deviceIndex != i)
+ deviceFeatures[i].isActiveDevice = false;
+ }
+ }
+ }
+ Log.e(TAG, "AVRCP isActive device index " + deviceIndex + " setActive addr " +
+ deviceFeatures[deviceIndex].mCurrentDevice.getAddress());
+
+ //to keep volume copy for setting volume
+ deviceFeatures[deviceIndex].mLocalVolume = getVolume(bt_device);
+ if((maxAvrcpConnections > 1) && (deviceFeatures[deviceIndex].mCurrentDevice != null)
+ && (deviceFeatures[deviceIndex].mReportedPlayerID != mCurrAddrPlayerID)) {
+ Log.d(TAG,"Update cache browsing event to last active device, deviceFeatures[" +
+ deviceIndex + "].mReportedPlayerID: " +
+ deviceFeatures[deviceIndex].mReportedPlayerID +
+ ", mCurrAddrPlayerID: " + mCurrAddrPlayerID);
+ if (deviceFeatures[deviceIndex].mAvailablePlayersChangedNT ==
+ AvrcpConstants.NOTIFICATION_TYPE_INTERIM) {
+ registerNotificationRspAvalPlayerChangedNative(
+ AvrcpConstants.NOTIFICATION_TYPE_CHANGED,
+ getByteAddress(deviceFeatures[deviceIndex].mCurrentDevice));
+ mAvailablePlayerViewChanged = false;
+ deviceFeatures[deviceIndex].mAvailablePlayersChangedNT =
+ AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
+ }
+ if (deviceFeatures[deviceIndex].mAddrPlayerChangedNT ==
+ AvrcpConstants.NOTIFICATION_TYPE_INTERIM) {
+ registerNotificationRspAddrPlayerChangedNative(
+ AvrcpConstants.NOTIFICATION_TYPE_CHANGED,
+ mCurrAddrPlayerID, sUIDCounter,
+ getByteAddress(deviceFeatures[deviceIndex].mCurrentDevice));
+ deviceFeatures[deviceIndex].mAddrPlayerChangedNT =
+ AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
+ // send track change event becasue some carkits will refresh metadata
+ // while receive addressed player change event. Track change event to
+ // make remote get metadata correctly.
+ sendTrackChangedRsp(false, deviceFeatures[deviceIndex].mCurrentDevice);
+ }
+
+ deviceFeatures[deviceIndex].mReportedPlayerID = mCurrAddrPlayerID;
+ break;
+ }
+
default:
Log.e(TAG, "unknown message! msg.what=" + msg.what);
break;
@@ -2638,10 +2796,19 @@
if (requested || ((deviceFeatures[i].mLastReportedPosition != playPositionMs) &&
((playPositionMs >= deviceFeatures[i].mNextPosMs) ||
(playPositionMs <= deviceFeatures[i].mPrevPosMs))) && deviceFeatures[i].isActiveDevice) {
- if (!requested) deviceFeatures[i].mPlayPosChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
- if (deviceFeatures[i].mCurrentDevice != null)
- registerNotificationRspPlayPosNative(deviceFeatures[i].mPlayPosChangedNT,
- (int)playPositionMs, getByteAddress(deviceFeatures[i].mCurrentDevice));
+ if (!requested)
+ deviceFeatures[i].mPlayPosChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
+ if (deviceFeatures[i].mCurrentDevice != null) {
+ if (!registerNotificationRspPlayPosNative(deviceFeatures[i].mPlayPosChangedNT,
+ (int)playPositionMs, getByteAddress(deviceFeatures[i].mCurrentDevice))) {
+ Log.w(TAG,"Fail to send rsp to remote, restore to interim if change rsp fail");
+ if (!requested) {
+ deviceFeatures[i].mPlayPosChangedNT =
+ AvrcpConstants.NOTIFICATION_TYPE_INTERIM;
+ return;
+ }
+ }
+ }
deviceFeatures[i].mLastReportedPosition = playPositionMs;
if (playPositionMs != PlaybackState.PLAYBACK_POSITION_UNKNOWN) {
deviceFeatures[i].mNextPosMs = playPositionMs + deviceFeatures[i].mPlaybackIntervalMs;
@@ -2745,23 +2912,23 @@
if (deviceFeatures[i].mCurrentDevice != null) {
Log.d(TAG, "SendPassThruPlay command sent for = "
+ deviceFeatures[i].mCurrentDevice);
- /*if (volume > mLocalVolume) {
+ if (volume > mLocalVolume) {
Log.d(TAG, "Vol Passthrough Up");
- avrcpCtrlService.sendPassThroughCmd(
- deviceFeatures[i].mCurrentDevice, AVRC_ID_VOL_UP,
- AvrcpConstants_ext.KEY_STATE_PRESS);
- avrcpCtrlService.sendPassThroughCmd(
- deviceFeatures[i].mCurrentDevice, AVRC_ID_VOL_UP,
- AvrcpConstants_ext.KEY_STATE_RELEASE);
+ avrcpCtrlService.sendPassThroughCommandNative(
+ Utils.getByteAddress(deviceFeatures[i].mCurrentDevice),
+ AVRC_ID_VOL_UP, AvrcpConstants_ext.KEY_STATE_PRESS);
+ avrcpCtrlService.sendPassThroughCommandNative(
+ Utils.getByteAddress(deviceFeatures[i].mCurrentDevice),
+ AVRC_ID_VOL_UP, AvrcpConstants_ext.KEY_STATE_RELEASE);
} else if (volume < mLocalVolume) {
Log.d(TAG, "Vol Passthrough Down");
- avrcpCtrlService.sendPassThroughCmd(
- deviceFeatures[i].mCurrentDevice, AVRC_ID_VOL_DOWN,
- AvrcpConstants_ext.KEY_STATE_PRESS);
- avrcpCtrlService.sendPassThroughCmd(
- deviceFeatures[i].mCurrentDevice, AVRC_ID_VOL_DOWN,
- AvrcpConstants_ext.KEY_STATE_RELEASE);
- }*/
+ avrcpCtrlService.sendPassThroughCommandNative(
+ Utils.getByteAddress(deviceFeatures[i].mCurrentDevice),
+ AVRC_ID_VOL_DOWN, AvrcpConstants_ext.KEY_STATE_PRESS);
+ avrcpCtrlService.sendPassThroughCommandNative(
+ Utils.getByteAddress(deviceFeatures[i].mCurrentDevice),
+ AVRC_ID_VOL_DOWN, AvrcpConstants_ext.KEY_STATE_RELEASE);
+ }
mLocalVolume = volume;
}
}
@@ -3278,6 +3445,11 @@
for (int i = 0; i < maxAvrcpConnections; i++ ) {
if (deviceFeatures[i].mCurrentDevice !=null &&
deviceFeatures[i].mCurrentDevice.equals(device)) {
+ if (deviceFeatures[i].isActiveDevice &&
+ deviceFeatures[i].isAbsoluteVolumeSupportingDevice) {
+ storeVolumeForDevice(device);
+ disconnectedActiveDevice = device;
+ }
// initiate cleanup for all variables;
Message msg = mHandler.obtainMessage(MESSAGE_DEVICE_RC_CLEANUP, STACK_CLEANUP,
0, device);
@@ -3307,6 +3479,8 @@
isTwsPlusPair(device,deviceFeatures[i].mCurrentDevice )) {
Log.i(TAG,"TWS+ pair got disconnected,update absVolume");
updateAbsVolume = true;
+ Log.i(TAG,"TWS+ pair disconnected, set mTwsPairDisconnected for index " + i);
+ deviceFeatures[i].mTwsPairDisconnected = true;
}
}
}
@@ -3325,7 +3499,11 @@
if ((mCurrentBrowsingDevice != null) &&
(mCurrentBrowsingDevice.equals(device))) {
Log.v(TAG,"BT device is matched with browsing device:");
- mAvrcpBrowseManager.cleanup();
+ BrowsedMediaPlayer_ext player =
+ mAvrcpBrowseManager.getBrowsedMediaPlayer(getByteAddress(device));
+ if (player != null)
+ player.disconnect();
+ mAvrcpBrowseManager.clearBrowsedMediaPlayer(getByteAddress(device));
mCurrentBrowsingDevice = null;
changePathDepth = 0;
changePathFolderType = 0;
@@ -3713,6 +3891,11 @@
synchronized (this) {
synchronized (mBrowsePlayerInfoList) {
mBrowsePlayerInfoList.clear();
+ BrowsedMediaPlayer_ext player =
+ mAvrcpBrowseManager.getBrowsedMediaPlayer(dummyaddr);
+ if (player != null)
+ player.start();
+ Log.d(TAG, "buildBrowsablePlayerList " + player);
Intent intent = new Intent(android.service.media.MediaBrowserService.SERVICE_INTERFACE);
List<ResolveInfo> playerList =
mPackageManager.queryIntentServices(intent, PackageManager.MATCH_ALL);
@@ -3723,8 +3906,10 @@
(displayName != null) ? displayName.toString():new String();
String serviceName = info.serviceInfo.name;
String packageName = info.serviceInfo.packageName;
-
- if (DEBUG) Log.d(TAG, "Adding " + serviceName + " to list of browsable players");
+ Log.d(TAG, "svc " + serviceName + " and pkg = " + packageName);
+ if ((player != null) && (serviceName != null)) {
+ player.CheckMBSConnection(packageName, serviceName);
+ }
BrowsePlayerInfo_ext currentPlayer =
new BrowsePlayerInfo_ext(packageName, displayableName, serviceName);
mBrowsePlayerInfoList.add(currentPlayer);
@@ -4097,13 +4282,25 @@
playStatusValues[idx] = info.getPlayStatus();
short[] featureBits = info.getFeatureBitMask();
- for (int numBit = 0; numBit < featureBits.length; numBit++) {
- /* gives which octet this belongs to */
- byte octet = (byte) (featureBits[numBit] / 8);
- /* gives the bit position within the octet */
- byte bit = (byte) (featureBits[numBit] % 8);
- featureBitMaskValues[(idx * AvrcpConstants_ext.AVRC_FEATURE_MASK_SIZE) + octet] |=
- (1 << bit);
+ short[] featureBitsArray = {0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x01, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ String browsedPackage = getPackageName(mCurrAddrPlayerID);
+ BrowsedMediaPlayer_ext player =
+ mAvrcpBrowseManager.getBrowsedMediaPlayer(dummyaddr);
+ if ((player != null) && (!browsedPackage.isEmpty()) &&
+ player.isPackageInMBSList(browsedPackage)) {
+ for (int numBit = 0; numBit < featureBits.length; numBit++) {
+ /* gives which octet this belongs to */
+ byte octet = (byte) (featureBits[numBit] / 8);
+ /* gives the bit position within the octet */
+ byte bit = (byte) (featureBits[numBit] % 8);
+ featureBitMaskValues[(idx * AvrcpConstants_ext.AVRC_FEATURE_MASK_SIZE) + octet] |=
+ (1 << bit);
+ }
+ } else {
+ featureBitMaskValues =
+ Arrays.copyOf(featureBitsArray, featureBitsArray.length);
+ Log.w(TAG, "sending bit mask for non Browsable Player");
}
/* printLogs */
@@ -4562,7 +4759,7 @@
if (connList.containsKey(bdaddrStr)) {
mediaPlayer = connList.get(bdaddrStr);
} else {
- mediaPlayer = new BrowsedMediaPlayer_ext(bdaddr, mContext, mMediaInterface);
+ mediaPlayer = new BrowsedMediaPlayer_ext(bdaddr, mContext, mMediaInterface, mAvrcp);
connList.put(bdaddrStr, mediaPlayer);
}
return mediaPlayer;
@@ -4921,6 +5118,19 @@
int storeVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
Log.i(TAG, "storeVolume: Storing stream volume level for device " + device
+ " : " + storeVolume);
+ if (index != INVALID_DEVICE_INDEX && deviceFeatures[index].isAbsoluteVolumeSupportingDevice &&
+ (mAbsVolThreshold > 0 && mAbsVolThreshold < mAudioStreamMax &&
+ storeVolume > mAbsVolThreshold)) {
+ if (DEBUG) Log.v(TAG, "remote store volume too high" + storeVolume + ">" +
+ mAbsVolThreshold);
+ storeVolume = mAbsVolThreshold;
+ }
+ if (index == INVALID_DEVICE_INDEX && disconnectedActiveDevice != null &&
+ disconnectedActiveDevice.equals(device)) {
+ Log.v(TAG, "No need to store volume again during avrcp disconnect volume is stored");
+ disconnectedActiveDevice = null;
+ return;
+ }
mVolumeMap.put(device, storeVolume);
pref.putInt(device.getAddress(), storeVolume);
if (device != null && device.isTwsPlusDevice()) {
@@ -4952,6 +5162,7 @@
Message msg = mHandler.obtainMessage(MESSAGE_START_SHO, PlayReq?1:0, 0, device);
SHOQueue.device = device;
SHOQueue.PlayReq = PlayReq;
+ SHOQueue.isRetry = false;
mHandler.sendMessageDelayed(msg, 3000);
Log.d(TAG, "4: SHO Queued");
return true;
@@ -4974,6 +5185,7 @@
}
mHandler.removeMessages(MESSAGE_START_SHO);
triggerSHO(device, PlayReq, true);
+ return ret;
}
synchronized (Avrcp_ext.this) {
if (!PlayReq || isInCall || isFMActive) {
@@ -4993,9 +5205,13 @@
private void triggerSHO(BluetoothDevice device, boolean PlayReq, boolean isRetry) {
Message msg = mHandler.obtainMessage(MESSAGE_START_SHO, PlayReq?1:0, isRetry?1:0, device);
if(isRetry) {
+ SHOQueue.device = device;
+ SHOQueue.PlayReq = PlayReq;
+ SHOQueue.isRetry = true;
mHandler.sendMessageDelayed(msg, 2000);
Log.e(TAG, "Retry SHO after delay");
} else {
+ SHOQueue.isRetry = false;
mHandler.sendMessage(msg);
}
}
@@ -5005,92 +5221,9 @@
}
public void setActiveDevice(BluetoothDevice device) {
- if (device == null) {
- for (int i = 0; i < maxAvrcpConnections; i++) {
- deviceFeatures[i].isActiveDevice = false;
- }
- return;
- }
- int deviceIndex = getIndexForDevice(device);
- if (deviceIndex == INVALID_DEVICE_INDEX) {
- Log.e(TAG,"Invalid device index for setActiveDevice");
- for (int i = 0; i < maxAvrcpConnections; i++) {
- deviceFeatures[i].isActiveDevice = false;
- }
- return;
- }
- deviceFeatures[deviceIndex].isActiveDevice = true;
-
- Log.w(TAG, "Active device Calling SetBrowsePackage for " + mCachedBrowsePlayer);
- if (mCachedBrowsePlayer != null && is_player_updated_for_browse == false) {
- SetBrowsePackage(mCachedBrowsePlayer);
- }
-
- if (updateAbsVolume == true && deviceFeatures[deviceIndex].mCurrentDevice.isTwsPlusDevice()) {
- Log.d(TAG,"setting absVolume flag for TWS+ device");
- mAudioManager.avrcpSupportsAbsoluteVolume(device.getAddress(),true);
- AdapterService mAdapterService = AdapterService.getAdapterService();
- BluetoothDevice peer_device =
- mAdapterService.getTwsPlusPeerDevice(deviceFeatures[deviceIndex].mCurrentDevice);
- if (peer_device != null &&
- getIndexForDevice(peer_device) == INVALID_DEVICE_INDEX) {
- Log.d(TAG,"Other TWS+ earbud not connected, reset updateAbsVolume flag");
- updateAbsVolume = false;
- }
- }
- if (maxAvrcpConnections > 1) {
- for (int i = 0; i < maxAvrcpConnections; i++) {
- if (deviceIndex != i && deviceFeatures[i].mCurrentDevice != null &&
- deviceFeatures[i].mCurrentDevice.isTwsPlusDevice() &&
- isTwsPlusPair(deviceFeatures[i].mCurrentDevice, device)) {
- Log.d(TAG,"TWS+ pair connected, keep both devices active");
- deviceFeatures[i].isActiveDevice = true;
- if (updateAbsVolume == true) {
- Log.d(TAG,"Setting absVolume flag to TWS+ pair");
- mAudioManager.avrcpSupportsAbsoluteVolume(device.getAddress(),true);
- updateAbsVolume = false;
- }
- } else {
- if(deviceIndex != i)
- deviceFeatures[i].isActiveDevice = false;
- }
- }
- }
- Log.e(TAG,"AVRCP setActive addr " + deviceFeatures[deviceIndex].mCurrentDevice.getAddress() +
- " isActive device index " + deviceIndex);
-
- //to keep volume copy for setting volume
- deviceFeatures[deviceIndex].mLocalVolume = getVolume(device);
- if ((maxAvrcpConnections > 1) && (deviceFeatures[deviceIndex].mCurrentDevice != null) &&
- (deviceFeatures[deviceIndex].mReportedPlayerID != mCurrAddrPlayerID)) {
- Log.d(TAG,"Update cached browsing events to latest active device, deviceFeatures[" +
- deviceIndex + "].mReportedPlayerID: " +
- deviceFeatures[deviceIndex].mReportedPlayerID +
- ", mCurrAddrPlayerID: " + mCurrAddrPlayerID);
- if (deviceFeatures[deviceIndex].mAvailablePlayersChangedNT ==
- AvrcpConstants_ext.NOTIFICATION_TYPE_INTERIM) {
- registerNotificationRspAvalPlayerChangedNative(
- AvrcpConstants_ext.NOTIFICATION_TYPE_CHANGED,
- getByteAddress(deviceFeatures[deviceIndex].mCurrentDevice));
- mAvailablePlayerViewChanged = false;
- deviceFeatures[deviceIndex].mAvailablePlayersChangedNT =
- AvrcpConstants_ext.NOTIFICATION_TYPE_CHANGED;
- }
- if (deviceFeatures[deviceIndex].mAddrPlayerChangedNT ==
- AvrcpConstants_ext.NOTIFICATION_TYPE_INTERIM) {
- registerNotificationRspAddrPlayerChangedNative(
- AvrcpConstants_ext.NOTIFICATION_TYPE_CHANGED, mCurrAddrPlayerID,
- sUIDCounter, getByteAddress(deviceFeatures[deviceIndex].mCurrentDevice));
- deviceFeatures[deviceIndex].mAddrPlayerChangedNT =
- AvrcpConstants_ext.NOTIFICATION_TYPE_CHANGED;
- // send track change event becasue some carkits will refresh metadata
- // while receive addressed player change event. Track change event to
- // make remote get metadata correctly.
- sendTrackChangedRsp(false, deviceFeatures[deviceIndex].mCurrentDevice);
- }
-
- deviceFeatures[deviceIndex].mReportedPlayerID = mCurrAddrPlayerID;
- }
+ Log.w(TAG, "setActiveDevice call for device " + device);
+ Message msg = mHandler.obtainMessage(MSG_SET_ACTIVE_DEVICE, 0, 0, device);
+ mHandler.sendMessage(msg);
}
private SharedPreferences getVolumeMap() {
diff --git a/packages_apps_bluetooth_ext/src/avrcp/BrowsedMediaPlayer_ext.java b/packages_apps_bluetooth_ext/src/avrcp/BrowsedMediaPlayer_ext.java
index 8f1801d..1327a4a 100644
--- a/packages_apps_bluetooth_ext/src/avrcp/BrowsedMediaPlayer_ext.java
+++ b/packages_apps_bluetooth_ext/src/avrcp/BrowsedMediaPlayer_ext.java
@@ -26,6 +26,10 @@
import android.media.session.MediaSession;
import android.os.Bundle;
import android.util.Log;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
import java.math.BigInteger;
import java.util.ArrayList;
@@ -48,6 +52,11 @@
private static final int CONNECTED = 1;
private static final int SUSPENDED = 2;
+ private static final int MSG_CONNECT_PLAYER = 1;
+ private static final int MSG_DISCONNECT_PLAYER = 2;
+ private static final int MSG_TIMEOUT = 3;
+
+ private static final int TIMEOUT = 3000;
private static final int BROWSED_ITEM_ID_INDEX = 2;
private static final int BROWSED_FOLDER_ID_INDEX = 4;
private static final String[] ROOT_FOLDER = {"root"};
@@ -59,10 +68,14 @@
private Context mContext;
private AvrcpMediaRspInterface_ext mMediaInterface;
private byte[] mBDAddr;
+ private Avrcp_ext mAvrcp = null;
private String mCurrentBrowsePackage;
private String mCurrentBrowseClass;
+ private BrowseMediaHandler mHandler = null;
+ private HandlerThread mHandlerThread;
+
/* Object used to connect to MediaBrowseService of Media Player */
private MediaBrowser mMediaBrowser = null;
private MediaController mMediaController = null;
@@ -89,6 +102,44 @@
/* store result of getfolderitems with scope="vfs" */
private List<MediaBrowser.MediaItem> mFolderItems = null;
+ private List<String> mBrowsablePlayerList = new ArrayList<String>();
+
+ class BrowseMediaHandler extends Handler {
+ BrowseMediaHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ Log.w(TAG, "handleMessage " + msg.what + " obj " + msg.obj);
+ switch (msg.what) {
+ case MSG_CONNECT_PLAYER:
+ Bundle data = msg.getData();
+ String packageName = data.getCharSequence("package").toString();
+ String cls = data.getCharSequence("class").toString();
+ Log.w(TAG, "package = " + packageName + " svc class " + cls);
+ MediaConnectionCallback callback = new MediaConnectionCallback(packageName);
+ MediaBrowser tempBrowser = new MediaBrowser(
+ mContext, new ComponentName(packageName, cls), callback, null);
+ callback.setBrowser(tempBrowser);
+ tempBrowser.connect();
+ Log.w(TAG, "TryconnectMBS with Browser service");
+ Message m = mHandler.obtainMessage(MSG_TIMEOUT, 0, 0, packageName);
+ mHandler.sendMessageDelayed(m, TIMEOUT);
+ break;
+ case MSG_DISCONNECT_PLAYER:
+ MediaBrowser mb = (MediaBrowser)msg.obj;
+ mb.disconnect();
+ Log.w(TAG, "Trigger disconnect for MediaBrowser " + mb);
+ break;
+ case MSG_TIMEOUT:
+ Log.w(TAG, "MSG_TIMEOUT");
+ break;
+ default:
+ break;
+ }
+ }
+ };
/* Connection state callback handler */
class MediaConnectionCallback extends MediaBrowser.ConnectionCallback {
@@ -100,15 +151,21 @@
}
public void setBrowser(MediaBrowser b) {
+ Log.d(TAG, "setBrowser " + b);
mBrowser = b;
}
@Override
public void onConnected() {
- mConnState = CONNECTED;
- if (DEBUG) {
- Log.d(TAG, "mediaBrowser CONNECTED to " + mPackageName);
+ if ((mHandler != null) && !mBrowsablePlayerList.contains(mCallbackPackageName)) {
+ Log.d(TAG, "Add " + mCallbackPackageName + " to MBS List " + mBrowser);
+ mBrowsablePlayerList.add(mCallbackPackageName);
+ mHandler.removeMessages(MSG_TIMEOUT, mCallbackPackageName);
+ Message msg = mHandler.obtainMessage(MSG_DISCONNECT_PLAYER, 0, 0, mBrowser);
+ mHandler.sendMessage(msg);
}
+ mConnState = CONNECTED;
+ Log.d(TAG, "mediaBrowser CONNECTED to " + mPackageName);
/* perform init tasks and set player as browsed player on successful connection */
onBrowseConnect(mCallbackPackageName, mBrowser);
@@ -118,17 +175,23 @@
@Override
public void onConnectionFailed() {
+ if ((mHandler != null) && !mBrowsablePlayerList.contains(mCallbackPackageName)) {
+ mHandler.removeMessages(MSG_TIMEOUT, mCallbackPackageName);
+ }
mConnState = DISCONNECTED;
// Remove what could be a circular dependency causing GC to never happen on this object
mBrowser = null;
Log.e(TAG, "mediaBrowser Connection failed with " + mPackageName
+ ", Sending fail response!");
- mMediaInterface.setBrowsedPlayerRsp(mBDAddr, AvrcpConstants_ext.RSP_INTERNAL_ERR,
+ mMediaInterface.setBrowsedPlayerRsp(mBDAddr, AvrcpConstants_ext.RSP_PLAY_NOT_BROW,
(byte) 0x00, 0, null);
}
@Override
public void onConnectionSuspended() {
+ if ((mHandler != null) && !mBrowsablePlayerList.contains(mCallbackPackageName)) {
+ mHandler.removeMessages(MSG_TIMEOUT, mCallbackPackageName);
+ }
mBrowser = null;
mConnState = SUSPENDED;
Log.e(TAG, "mediaBrowser SUSPENDED connection with " + mPackageName);
@@ -281,10 +344,11 @@
/* Constructor */
BrowsedMediaPlayer_ext(byte[] address, Context context,
- AvrcpMediaRspInterface_ext mAvrcpMediaRspInterface) {
+ AvrcpMediaRspInterface_ext mAvrcpMediaRspInterface, Avrcp_ext mAvrcp_ext) {
mContext = context;
mMediaInterface = mAvrcpMediaRspInterface;
mBDAddr = address;
+ mAvrcp = mAvrcp_ext;
}
/* initialize mediacontroller in order to communicate with media player. */
@@ -478,18 +542,80 @@
Log.w(TAG, "Reconnected with Browser service");
}
+ public void CheckMBSConnection(String packageName, String cls) {
+ Log.w(TAG, "TryconnectMBS with Browser service for package = " + packageName);
+ Message msg = mHandler.obtainMessage(MSG_CONNECT_PLAYER);
+ Bundle data = new Bundle();
+ data.putCharSequence("package", packageName);
+ data.putCharSequence("class", cls);
+ msg.setData(data);
+ mHandler.sendMessage(msg);
+ Log.w(TAG, "Exit MSG_CONNECT_PLAYER for package = " + packageName);
+ }
+
+ public boolean isPackageInMBSList(String packageName) {
+ if (packageName == null || packageName.isEmpty())
+ return false;
+ Log.w(TAG, "isPlayerConnectedMBS for package = " + packageName);
+
+ // Wait while pending messages are in queue
+ while ((mHandler != null) && (mHandler.hasMessages(MSG_CONNECT_PLAYER)
+ || mHandler.hasMessages(MSG_TIMEOUT))) {
+ try {
+ Log.d(TAG, "Connection with MBS ongoing, sleep for 200 ms and recheck");
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ Log.w(TAG, "Interrupt sleep caught Exception");
+ }
+ }
+
+ Log.w(TAG, "List of Browse supported players = " + mBrowsablePlayerList);
+ for (String pkg : mBrowsablePlayerList) {
+ if (packageName.equals(pkg))
+ return true;
+ }
+ return false;
+ }
+
public void setCurrentPackage(String packageName, String cls) {
Log.w(TAG, "Set current Browse based on Addr Player as " + packageName);
mCurrentBrowsePackage = packageName;
mCurrentBrowseClass = cls;
}
+ public void start() {
+ if (mHandler == null) {
+ Log.w(TAG, "start");
+ mHandlerThread = new HandlerThread("BrowseMediaHandler");
+ mHandlerThread.start();
+ mHandler = new BrowseMediaHandler(mHandlerThread.getLooper());
+ }
+ Log.w(TAG, "start exit");
+ }
+
/* called when connection to media player is closed */
public void cleanup() {
+ disconnect();
if (DEBUG) {
Log.d(TAG, "cleanup");
}
+ mBrowsablePlayerList.clear();
+ if (mHandler != null) {
+ Log.d(TAG, "cleanup handlers");
+ mHandler.removeCallbacksAndMessages(null);
+ Looper looper = mHandler.getLooper();
+ if (looper != null)
+ looper.quit();
+ }
+ if (mHandlerThread != null) {
+ mHandlerThread.quitSafely();
+ }
+ }
+ public void disconnect() {
+ if (DEBUG) {
+ Log.d(TAG, "disconnect");
+ }
if (mConnState != DISCONNECTED) {
if (mMediaBrowser != null) mMediaBrowser.disconnect();
}
@@ -852,7 +978,7 @@
mMediaInterface.folderItemsRsp(bdaddr, AvrcpConstants_ext.RSP_NO_ERROR, rspObj);
}
- public String getAttrValue(byte []bdaddr, int attr, MediaBrowser.MediaItem item) {
+ public String getAttrValue(byte[] bdaddr, int attr, MediaBrowser.MediaItem item) {
String attrValue = null;
try {
MediaDescription desc = item.getDescription();
@@ -888,8 +1014,12 @@
break;
case AvrcpConstants_ext.ATTRID_COVER_ART:
- attrValue = Avrcp_ext.getImgHandleFromTitle(bdaddr,
- desc.getTitle().toString());
+ if (mAvrcp != null && mAvrcp.isCoverArtFeatureSupported(bdaddr)) {
+ attrValue = Avrcp_ext.getImgHandleFromTitle(bdaddr,
+ desc.getTitle().toString());
+ } else {
+ attrValue = null;
+ }
break;
default:
diff --git a/packages_apps_bluetooth_ext/src/ba/BATService.java b/packages_apps_bluetooth_ext/src/ba/BATService.java
index b658a67..5f6a01b 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
@@ -453,7 +664,7 @@
if((mPrevStackBATState == BA_STACK_STATE_PENDING) &&
(mCurrStackBATState == BA_STACK_STATE_PAUSED)) {
Log.d(TAG," updating AudioManager: Connected for BA ");
- mAudioManager.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
+ mAudioManager.handleBluetoothA2dpActiveDeviceChange(
mBADevice, BluetoothProfile.STATE_CONNECTED,BluetoothProfile.A2DP, true, -1);
//BA audio works on the principal of absVol
//Currently mm-audio tracks value of last updated absVol support,
@@ -471,13 +682,13 @@
// as a2dp has to be updated as well. Switching should happen to
// A2DP in this case.
Log.d(TAG," updating AudioManager: Connected for A2DP ");
- mAudioManager.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
+ mAudioManager.handleBluetoothA2dpActiveDeviceChange(
a2dpActiveDevice, BluetoothProfile.STATE_CONNECTED,BluetoothProfile.A2DP,
true, -1);
} else {// a2dp active device is null.
// inform BA device as disconnected. we have to send noisy intent
// because BA seems to be last device.
- mAudioManager.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
+ mAudioManager.handleBluetoothA2dpActiveDeviceChange(
mBADevice, BluetoothProfile.STATE_DISCONNECTED,BluetoothProfile.A2DP,
false, -1);
}
@@ -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();
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
diff --git a/packages_apps_bluetooth_ext/src/btservice/Vendor.java b/packages_apps_bluetooth_ext/src/btservice/Vendor.java
index 685807a..31338db 100644
--- a/packages_apps_bluetooth_ext/src/btservice/Vendor.java
+++ b/packages_apps_bluetooth_ext/src/btservice/Vendor.java
@@ -56,6 +56,7 @@
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothQualityReport;
import com.android.bluetooth.Utils;
import android.content.Intent;
@@ -184,6 +185,31 @@
mService.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
}
+ private void bqrDeliver(byte[] remoteAddr,
+ int lmpVer, int lmpSubVer, int manufacturerId, byte[] bqrRawData) {
+ String remoteName = "";
+ int remoteCoD = 0;
+ String addr = Utils.getAddressStringFromByte(remoteAddr);
+ if (addr != null) {
+ BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(addr);
+ remoteName = mService.getRemoteName(device);
+ remoteCoD = mService.getRemoteClass(device);
+ }
+
+ BluetoothQualityReport bqr;
+ try {
+ bqr = new BluetoothQualityReport(addr, lmpVer, lmpSubVer,
+ manufacturerId, remoteName, remoteCoD, bqrRawData);
+ } catch (Exception e) {
+ Log.e(TAG, "bqrDeliver: failed to create bqr", e);
+ return;
+ }
+ Log.d(TAG, "" + bqr);
+ Intent intent = new Intent(BluetoothDevice.ACTION_REMOTE_ISSUE_OCCURRED);
+ intent.putExtra(BluetoothDevice.EXTRA_BQR, bqr);
+ mService.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
+ }
+
void ssr_cleanup_callback() {
Log.e(TAG,"ssr_cleanup_callback");
mService.ssrCleanupCallback();
diff --git a/packages_apps_bluetooth_ext/src/hfp/vendorhfservice.java b/packages_apps_bluetooth_ext/src/hfp/vendorhfservice.java
index aab40ef..2309ee1 100644
--- a/packages_apps_bluetooth_ext/src/hfp/vendorhfservice.java
+++ b/packages_apps_bluetooth_ext/src/hfp/vendorhfservice.java
@@ -74,10 +74,10 @@
}
private void onTwsBatteryStateCallback(String atString, byte[] address) {
- /*HeadsetStackEvent event = new HeadsetStackEvent(
- HeadsetStackEvent.EVENT_TYPE_TWSP_BATTERY_STATE, atString,
- getDevice(address));
- sendMessageToService(event);*/
+ HeadsetStackEvent event =
+ new HeadsetStackEvent(HeadsetStackEvent.EVENT_TYPE_TWSP_BATTERY_STATE, atString,
+ getDevice(address));
+ sendMessageToService(event);
}
private void sendMessageToService(HeadsetStackEvent event) {
diff --git a/packages_apps_bluetooth_ext/src/map/src/BluetoothMapFixes.java b/packages_apps_bluetooth_ext/src/map/src/BluetoothMapFixes.java
index 443cfb1..c91e380 100644
--- a/packages_apps_bluetooth_ext/src/map/src/BluetoothMapFixes.java
+++ b/packages_apps_bluetooth_ext/src/map/src/BluetoothMapFixes.java
@@ -273,4 +273,10 @@
}
return !ismap14Enabled;
}
+
+ static boolean isRebonded(BluetoothDevice remoteDevice) {
+ String isRebonded = mapSdpResponse.get(
+ remoteDevice.getAddress().substring(0,8));
+ return ((isRebonded != null) && isRebonded.equalsIgnoreCase("Y"));
+ }
}
diff --git a/packages_apps_bluetooth_ext/src/pbap/BluetoothPbapFixes.java b/packages_apps_bluetooth_ext/src/pbap/BluetoothPbapFixes.java
index a4b647b..b1307a0 100644
--- a/packages_apps_bluetooth_ext/src/pbap/BluetoothPbapFixes.java
+++ b/packages_apps_bluetooth_ext/src/pbap/BluetoothPbapFixes.java
@@ -521,4 +521,11 @@
mNotificationManager.cancelAll();
}
}
+
+ static boolean isRebonded(BluetoothDevice remoteDevice) {
+ String isRebonded = PbapSdpResponse.get(
+ remoteDevice.getAddress().substring(0,8));
+ return ((isRebonded != null) && isRebonded.equalsIgnoreCase("Y"));
+ }
+
}
diff --git a/system_bt_ext/bta/include/bta_ag_swb.h b/system_bt_ext/bta/include/bta_ag_swb.h
index a65f3c3..3fb096e 100644
--- a/system_bt_ext/bta/include/bta_ag_swb.h
+++ b/system_bt_ext/bta/include/bta_ag_swb.h
@@ -46,7 +46,7 @@
#define BTA_AG_LOCAL_RES_QCS 0x109
#define LEGACY_CODECS 2
-#define SWB_ESCO_NUM_CODECS 1
+#define SWB_ESCO_NUM_CODECS 4
void bta_ag_swb_handle_vs_at_events(tBTA_AG_SCB* p_scb, uint16_t cmd, int16_t int_arg, tBTA_AG_VAL val);
void bta_ag_send_qac(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data);
@@ -54,6 +54,7 @@
tBTA_AG_PEER_CODEC bta_ag_parse_qac(tBTA_AG_SCB* p_scb, char* p_s);
const enh_esco_params_t default_esco_swb_parameters[SWB_ESCO_NUM_CODECS] = {
+ // ESCO_CODEC_SWB_Q0
{.transmit_bandwidth = TXRX_64KBITS_RATE,
.receive_bandwidth = TXRX_64KBITS_RATE,
.transmit_coding_format = {.coding_format = ESCO_CODING_FORMAT_VS,
@@ -84,6 +85,103 @@
.output_transport_unit_size = 0x00,
.max_latency_ms = 14,
.packet_types = 0x0380,
- .retransmission_effort = ESCO_RETRANSMISSION_QUALITY}};
+ .retransmission_effort = ESCO_RETRANSMISSION_QUALITY},
+ // ESCO_CODEC_SWB_Q1
+ {.transmit_bandwidth = TXRX_64KBITS_RATE,
+ .receive_bandwidth = TXRX_64KBITS_RATE,
+ .transmit_coding_format = {.coding_format = ESCO_CODING_FORMAT_VS,
+ .company_id = 0x000A,
+ .vendor_specific_codec_id = 0x0000},
+ .receive_coding_format = {.coding_format = ESCO_CODING_FORMAT_VS,
+ .company_id = 0x000A,
+ .vendor_specific_codec_id = 0x0000},
+ .transmit_codec_frame_size = 60,
+ .receive_codec_frame_size = 60,
+ .input_bandwidth = INPUT_OUTPUT_128K_RATE,
+ .output_bandwidth = INPUT_OUTPUT_128K_RATE,
+ .input_coding_format = {.coding_format = ESCO_CODING_FORMAT_LINEAR,
+ .company_id = 0x0000,
+ .vendor_specific_codec_id = 0x0000},
+ .output_coding_format = {.coding_format = ESCO_CODING_FORMAT_LINEAR,
+ .company_id = 0x0000,
+ .vendor_specific_codec_id = 0x0000},
+ .input_coded_data_size = 16,
+ .output_coded_data_size = 16,
+ .input_pcm_data_format = ESCO_PCM_DATA_FORMAT_2_COMP,
+ .output_pcm_data_format = ESCO_PCM_DATA_FORMAT_2_COMP,
+ .input_pcm_payload_msb_position = 0,
+ .output_pcm_payload_msb_position = 0,
+ .input_data_path = ESCO_DATA_PATH_PCM,
+ .output_data_path = ESCO_DATA_PATH_PCM,
+ .input_transport_unit_size = 0x00,
+ .output_transport_unit_size = 0x00,
+ .max_latency_ms = 14,
+ .packet_types = 0x0380,
+ .retransmission_effort = ESCO_RETRANSMISSION_QUALITY},
+ // ESCO_CODEC_SWB_Q2
+ {.transmit_bandwidth = TXRX_64KBITS_RATE,
+ .receive_bandwidth = TXRX_64KBITS_RATE,
+ .transmit_coding_format = {.coding_format = ESCO_CODING_FORMAT_VS,
+ .company_id = 0x000A,
+ .vendor_specific_codec_id = 0x0000},
+ .receive_coding_format = {.coding_format = ESCO_CODING_FORMAT_VS,
+ .company_id = 0x000A,
+ .vendor_specific_codec_id = 0x0000},
+ .transmit_codec_frame_size = 60,
+ .receive_codec_frame_size = 60,
+ .input_bandwidth = INPUT_OUTPUT_128K_RATE,
+ .output_bandwidth = INPUT_OUTPUT_128K_RATE,
+ .input_coding_format = {.coding_format = ESCO_CODING_FORMAT_LINEAR,
+ .company_id = 0x0000,
+ .vendor_specific_codec_id = 0x0000},
+ .output_coding_format = {.coding_format = ESCO_CODING_FORMAT_LINEAR,
+ .company_id = 0x0000,
+ .vendor_specific_codec_id = 0x0000},
+ .input_coded_data_size = 16,
+ .output_coded_data_size = 16,
+ .input_pcm_data_format = ESCO_PCM_DATA_FORMAT_2_COMP,
+ .output_pcm_data_format = ESCO_PCM_DATA_FORMAT_2_COMP,
+ .input_pcm_payload_msb_position = 0,
+ .output_pcm_payload_msb_position = 0,
+ .input_data_path = ESCO_DATA_PATH_PCM,
+ .output_data_path = ESCO_DATA_PATH_PCM,
+ .input_transport_unit_size = 0x00,
+ .output_transport_unit_size = 0x00,
+ .max_latency_ms = 14,
+ .packet_types = 0x0380,
+ .retransmission_effort = ESCO_RETRANSMISSION_QUALITY},
+ // ESCO_CODEC_SWB_Q3
+ {.transmit_bandwidth = TXRX_64KBITS_RATE,
+ .receive_bandwidth = TXRX_64KBITS_RATE,
+ .transmit_coding_format = {.coding_format = ESCO_CODING_FORMAT_VS,
+ .company_id = 0x000A,
+ .vendor_specific_codec_id = 0x0000},
+ .receive_coding_format = {.coding_format = ESCO_CODING_FORMAT_VS,
+ .company_id = 0x000A,
+ .vendor_specific_codec_id = 0x0000},
+ .transmit_codec_frame_size = 60,
+ .receive_codec_frame_size = 60,
+ .input_bandwidth = INPUT_OUTPUT_128K_RATE,
+ .output_bandwidth = INPUT_OUTPUT_128K_RATE,
+ .input_coding_format = {.coding_format = ESCO_CODING_FORMAT_LINEAR,
+ .company_id = 0x0000,
+ .vendor_specific_codec_id = 0x0000},
+ .output_coding_format = {.coding_format = ESCO_CODING_FORMAT_LINEAR,
+ .company_id = 0x0000,
+ .vendor_specific_codec_id = 0x0000},
+ .input_coded_data_size = 16,
+ .output_coded_data_size = 16,
+ .input_pcm_data_format = ESCO_PCM_DATA_FORMAT_2_COMP,
+ .output_pcm_data_format = ESCO_PCM_DATA_FORMAT_2_COMP,
+ .input_pcm_payload_msb_position = 0,
+ .output_pcm_payload_msb_position = 0,
+ .input_data_path = ESCO_DATA_PATH_PCM,
+ .output_data_path = ESCO_DATA_PATH_PCM,
+ .input_transport_unit_size = 0x00,
+ .output_transport_unit_size = 0x00,
+ .max_latency_ms = 14,
+ .packet_types = 0x0380,
+ .retransmission_effort = ESCO_RETRANSMISSION_QUALITY}
+};
#endif//_BTA_AG_SWB_H_
diff --git a/system_bt_ext/bta/tws_plus/ag/bta_ag_twsp_dev.cc b/system_bt_ext/bta/tws_plus/ag/bta_ag_twsp_dev.cc
index d2c25c4..7068c15 100644
--- a/system_bt_ext/bta/tws_plus/ag/bta_ag_twsp_dev.cc
+++ b/system_bt_ext/bta/tws_plus/ag/bta_ag_twsp_dev.cc
@@ -596,6 +596,11 @@
int i;
char* p;
+ if (p_s == NULL) {
+ APPL_TRACE_ERROR("%s: Invalid Argument", __func__);
+ return false;
+ }
+
for (i = 0; i < 2; i++) {
/* skip to comma delimiter */
for (p = p_s; *p != ',' && *p != 0; p++)
diff --git a/system_bt_ext/btconfigstore/bt_configstore.cc b/system_bt_ext/btconfigstore/bt_configstore.cc
index 4f91bbf..0e05453 100644
--- a/system_bt_ext/btconfigstore/bt_configstore.cc
+++ b/system_bt_ext/btconfigstore/bt_configstore.cc
@@ -49,12 +49,15 @@
#include <hwbinder/ProcessState.h>
#include <string.h>
+#include <hwbinder/IPCThreadState.h>
+#include <cutils/properties.h>
/* max platform record must be equal to the predefined max num
of platform in bt_configstore.conf */
#define MAX_PLATFORM_PROP_RECORD 12
#define BT_CONFIG_STORE_PATH "/etc/bluetooth/bt_configstore.conf"
+using android::hardware::IPCThreadState;
using ::vendor::qti::hardware::btconfigstore::V1_0::IBTConfigStore;
using ::vendor::qti::hardware::btconfigstore::V1_0::VendorProperty;
using ::vendor::qti::hardware::btconfigstore::V1_0::AddOnFeaturesList;
@@ -79,6 +82,7 @@
static bt_soc_type_t convertSocNameToBTSocType(const char * name);
static const char * convertPropTypeToStringFormat(uint32_t propType);
+const bool IsLazyHalSupported(property_get_bool("ro.vendor.bt.enablelazyhal", false));
EXPORT_SYMBOL bt_configstore_interface_t btConfigStoreInterface = {
sizeof(btConfigStoreInterface),
@@ -89,6 +93,7 @@
convertPropTypeToStringFormat,
};
+
/*******************************************************************************
**
** Function getVendorProperties
@@ -104,6 +109,8 @@
*******************************************************************************/
static bool getVendorProperties(uint32_t vPropType, std::vector<vendor_property_t> &vPropList)
{
+ bool status = false;
+
LOG_INFO(LOG_TAG, "%s ", __func__);
if (btConfigStore == nullptr)
@@ -131,18 +138,23 @@
LOG_INFO(LOG_TAG, "prop type: %s, prop_value: %s",
convertPropTypeToStringFormat(vProp.type), vProp.value);
}
- return true;
+ status = true;
}
} else {
LOG_WARN(LOG_TAG,"%s btConfigStore hal interface is null", __func__);
if (btConfigStoreLoadProperties(vPropType, vPropList)){
LOG_INFO(LOG_TAG, "Properties are successfully read from %s",
BT_CONFIG_STORE_PATH);
- return true;
+
+ status = true;
}
}
- return false;
+ if (IsLazyHalSupported && btConfigStore != nullptr)
+ IPCThreadState::self()->flushCommands();
+
+ btConfigStore = nullptr;
+ return status;
}
/*******************************************************************************
@@ -160,6 +172,8 @@
*******************************************************************************/
static bool setVendorProperty(uint32_t type, const char * value)
{
+ bool status = false;
+
LOG_INFO(LOG_TAG, "%s ", __func__);
if (btConfigStore == nullptr)
@@ -173,12 +187,17 @@
LOG_INFO(LOG_TAG, "%s:: halResult = %d", __func__, halResult);
if (halResult == Result::SUCCESS){
- return true;
+ status = true;
}
} else {
LOG_WARN(LOG_TAG, "%s btConfigStore is null", __func__);
}
- return false;
+
+ if (IsLazyHalSupported && btConfigStore != nullptr)
+ IPCThreadState::self()->flushCommands();
+
+ btConfigStore = nullptr;
+ return status;
}
/*******************************************************************************
@@ -196,6 +215,8 @@
*******************************************************************************/
static bool getAddOnFeatures(add_on_features_list_t *features_list)
{
+ bool status = false;
+
LOG_INFO(LOG_TAG, "%s ", __func__);
if (btConfigStore == nullptr)
@@ -232,13 +253,17 @@
"%s:: product_id = %d, version = %d, feat_mask_len = %d features data: %s",
__func__, features_list->product_id, features_list->rsp_version,
features_list->feat_mask_len, features);
- return true;
+ status = true;
}
} else {
LOG_WARN(LOG_TAG, "%s add feature is not avaliable", __func__);
}
- return false;
+ if (IsLazyHalSupported && btConfigStore != nullptr)
+ IPCThreadState::self()->flushCommands();
+
+ btConfigStore = nullptr;
+ return status;
}
/*******************************************************************************
@@ -348,6 +373,22 @@
LOG_INFO(LOG_TAG, "%s:: prop type: %s, prop value: %s", __func__,
convertPropTypeToStringFormat(vProp.type), vProp.value);
vPropList.push_back(vProp);
+
+ vProp.type = BT_PROP_A2DP_MCAST_TEST;
+ strlcpy(vProp.value,
+ config_get_string(config, section_name, "a2dpMcastSupported", "null"),
+ sizeof(vProp.value));
+ LOG_INFO(LOG_TAG, "%s:: prop type: %s, prop value: %s", __func__,
+ convertPropTypeToStringFormat(vProp.type), vProp.value);
+ vPropList.push_back(vProp);
+
+ vProp.type = BT_PROP_TWSP_STATE;
+ strlcpy(vProp.value,
+ config_get_string(config, section_name, "twspStateSupported", "null"),
+ sizeof(vProp.value));
+ LOG_INFO(LOG_TAG, "%s:: prop type: %s, prop value: %s", __func__,
+ convertPropTypeToStringFormat(vProp.type), vProp.value);
+ vPropList.push_back(vProp);
break;
case BT_PROP_SOC_TYPE:
@@ -399,6 +440,25 @@
convertPropTypeToStringFormat(vProp.type), vProp.value);
vPropList.push_back(vProp);
break;
+ case BT_PROP_A2DP_MCAST_TEST:
+ vProp.type = BT_PROP_A2DP_MCAST_TEST;
+ strlcpy(vProp.value,
+ config_get_string(config, section_name, "a2dpMcastSupported", "null"),
+ sizeof(vProp.value));
+ LOG_INFO(LOG_TAG, "%s:: prop type: %s, prop value: %s", __func__,
+ convertPropTypeToStringFormat(vProp.type), vProp.value);
+ vPropList.push_back(vProp);
+ break;
+
+ case BT_PROP_TWSP_STATE:
+ vProp.type = BT_PROP_TWSP_STATE;
+ strlcpy(vProp.value,
+ config_get_string(config, section_name, "twspStateSupported", "null"),
+ sizeof(vProp.value));
+ LOG_INFO(LOG_TAG, "%s:: prop type: %s, prop value: %s", __func__,
+ convertPropTypeToStringFormat(vProp.type), vProp.value);
+ vPropList.push_back(vProp);
+ break;
default:
LOG_INFO(LOG_TAG, "%s:: prop type not handled %d", __func__, vPropType);
diff --git a/system_bt_ext/btconfigstore/bt_configstore.conf b/system_bt_ext/btconfigstore/bt_configstore.conf
index 346cbd3..b52fb64 100644
--- a/system_bt_ext/btconfigstore/bt_configstore.conf
+++ b/system_bt_ext/btconfigstore/bt_configstore.conf
@@ -19,6 +19,8 @@
# Wipower Support - true(default) or false
wiPowerSupported = true
+# TWS+ state processing
+twspStateSupported = false;
#=================================================================================================#
# platform configuration
[platform2]
@@ -41,6 +43,8 @@
# Wipower Support - true(default) or false
wiPowerSupported = true
+# TWS+ state processing
+twspStateSupported = false;
#=================================================================================================#
# platform configuration
[platform3]
@@ -63,6 +67,8 @@
# Wipower Support - true(default) or false
wiPowerSupported = true
+# TWS+ state processing
+twspStateSupported = false;
#=================================================================================================#
# platform configuration
[platform4]
@@ -85,6 +91,8 @@
# Wipower Support - true(default) or false
wiPowerSupported = true
+# TWS+ state processing
+twspStateSupported = false;
#=================================================================================================#
# platform configuration
[platform5]
@@ -129,6 +137,11 @@
# Wipower Support - true(default) or false
wiPowerSupported = true
+#A2dp Multicast support
+a2dpMcastSupported = false;
+
+# TWS+ state processing
+twspStateSupported = false;
#=================================================================================================#
# platform configuration
[platform7]
@@ -247,4 +260,4 @@
aacFrameCtlEnabled = false
# Wipower Support - true or false (default)
-wiPowerSupported = false
\ No newline at end of file
+wiPowerSupported = false
diff --git a/system_bt_ext/btif/include/btif_twsp_hf.h b/system_bt_ext/btif/include/btif_twsp_hf.h
index 0b11ca9..2c9c7c4 100644
--- a/system_bt_ext/btif/include/btif_twsp_hf.h
+++ b/system_bt_ext/btif/include/btif_twsp_hf.h
@@ -47,5 +47,7 @@
int btif_hf_get_other_connected_twsp_index(int idx);
+void btif_hf_twsp_send_bvra_update(int idx, tBTA_AG_RES_DATA* ag_res);
+
} // namespace headset
} // namespace bluetooth
diff --git a/system_bt_ext/btif/src/btif_twsp_hf.cc b/system_bt_ext/btif/src/btif_twsp_hf.cc
index 52ab07d..029df6d 100644
--- a/system_bt_ext/btif/src/btif_twsp_hf.cc
+++ b/system_bt_ext/btif/src/btif_twsp_hf.cc
@@ -123,6 +123,24 @@
return btif_max_hf_clients;
}
+/*******************************************************************************
+**
+** Function btif_hf_twsp_send_bvra_update
+**
+** Description Send BVRA update for connected TWS+ peer earbud
+**
+** Returns void
+**
+*******************************************************************************/
+
+void btif_hf_twsp_send_bvra_update(int current_index, tBTA_AG_RES_DATA* ag_res) {
+ int peer_eb_idx = btif_hf_get_other_connected_twsp_index(current_index);
+ if ((peer_eb_idx >= 0) && (peer_eb_idx < BTA_AG_MAX_NUM_CLIENTS) &&
+ (btif_hf_cb[peer_eb_idx].peer_feat & BTA_AG_PEER_FEAT_VREC)) {
+ BTIF_TRACE_DEBUG("%s: Send BVRA update for peer earbud, idx: %d", __func__, peer_eb_idx);
+ BTA_AgResult(btif_hf_cb[peer_eb_idx].handle, BTA_AG_BVRA_RES, ag_res);
+ }
+}
} // namespace headset
} // namespace bluetooth
diff --git a/system_bt_ext/btif/src/btif_vendor.cc b/system_bt_ext/btif/src/btif_vendor.cc
index b5d0172..b8dbcf8 100644
--- a/system_bt_ext/btif/src/btif_vendor.cc
+++ b/system_bt_ext/btif/src/btif_vendor.cc
@@ -62,10 +62,14 @@
#include <hardware/vendor.h>
#include <stdlib.h>
#include <string.h>
+#include <vector>
#define LOG_TAG "bt_btif_vendor"
#include <cutils/properties.h>
+#include <base/bind.h>
+#include <base/callback.h>
+#include <base/location.h>
#include "bt_utils.h"
#include "btif_common.h"
#include "btif_util.h"
@@ -297,6 +301,43 @@
manufacturer_id, power_level, rssi, link_quality,
glitch_count);
}
+
+void btif_vendor_bqr_delivery_event(const RawAddress* bd_addr, const uint8_t* bqr_raw_data,
+ uint32_t bqr_raw_data_len)
+{
+ if (bd_addr == NULL) {
+ LOG_ERROR(LOG_TAG, "%s: addr is null", __func__);
+ return;
+ }
+
+ if (bqr_raw_data == NULL) {
+ LOG_ERROR(LOG_TAG, "%s: bqr data is null", __func__);
+ return;
+ }
+
+ std::vector<uint8_t> raw_data;
+ raw_data.insert(raw_data.begin(), bqr_raw_data, bqr_raw_data + bqr_raw_data_len);
+
+ uint8_t lmp_ver = 0;
+ uint16_t lmp_subver = 0;
+ uint16_t manufacturer_id = 0;
+ btif_vendor_get_remote_version(bd_addr, &lmp_ver, &manufacturer_id, &lmp_subver);
+
+ LOG_INFO(LOG_TAG, "%s: len: %d, addr: %s, lmp_ver: %d, manufacturer_id: %d, lmp_subver: %d",
+ __func__, bqr_raw_data_len, bd_addr->ToString().c_str(), lmp_ver,
+ manufacturer_id, lmp_subver);
+
+ do_in_jni_thread(
+ FROM_HERE,
+ base::Bind(
+ [](RawAddress addr, uint8_t lmp_ver, uint16_t lmp_subver, uint16_t manufacturer_id,
+ std::vector<uint8_t> raw_data) {
+ HAL_CBACK(bt_vendor_callbacks, bqr_delivery_cb, &addr,
+ lmp_ver, lmp_subver, manufacturer_id, std::move(raw_data));
+ },
+ *bd_addr, lmp_ver, lmp_subver, manufacturer_id, std::move(raw_data)));
+}
+
static void bredrstartup(void)
{
LOG_INFO(LOG_TAG,"bredrstartup");
diff --git a/system_bt_ext/conf/bt_profile.conf b/system_bt_ext/conf/bt_profile.conf
index 8082534..d3fd677 100644
--- a/system_bt_ext/conf/bt_profile.conf
+++ b/system_bt_ext/conf/bt_profile.conf
@@ -7,7 +7,7 @@
# 1.AVRCP
# 2.PBAP
# 3.MAP
-# 4.MAX_PWR
+# 4.MAX_POW
#
# ******************************* Start of config Database *******************
#AVRCP profile and its configurable features
@@ -32,14 +32,14 @@
map_email_support = true
map_0104_support = true
-#Configurable BT MAX_PWR based on BT Technology
+#Configurable BT MAX_POW based on BT Technology
#Host can specify different max. power for different Technology/packet type
#Currently BR,EDR and BLE packet type are supported
-#Power value 0XFF is meant to disable the max power restriction for particular technology
-# BR_max_pow_support default value 0xFF
-# EDR_max_pow_support default value 0xFF
-# BLE_max_pow_support default value 0xFF
+#Power value 0x80 is meant to disable the max power restriction for particular technology
+# BR_max_pow_support default value 0x80
+# EDR_max_pow_support default value 0x80
+# BLE_max_pow_support default value 0x80
[MAX_POW]
-#BR_max_pow_support = 0xFF
-#EDR_max_pow_support = 0xFF
+#BR_max_pow_support = 0x80
+#EDR_max_pow_support = 0x80
BLE_max_pow_support = 0x18
diff --git a/system_bt_ext/conf/interop_database.conf b/system_bt_ext/conf/interop_database.conf
index 1edf231..eb8afac 100644
--- a/system_bt_ext/conf/interop_database.conf
+++ b/system_bt_ext/conf/interop_database.conf
@@ -79,6 +79,7 @@
00:18:91 = Address_Based
00:24:1C = Address_Based
00:08:8b = Address_Based
+94:16:25 = Address_Based
# Disable automatic pairing with headsets/car-kits
# Some car kits do not react kindly to a failed pairing attempt and
@@ -345,6 +346,27 @@
XAV-AX100 = Name_Based
00:18:6b = Address_Based
LG HBS730 = Name_Based
+8C:57:9B = Address_Based
+h.ear go (SRS-HG1) = Name_Based
+40:ED:98 = Address_Based
+FiiO BTR1K = Name_Based
+0C:A6:94 = Address_Based
+HK Soho Wireless = Name_Based
+00:09:A7 = Address_Based
+Beoplay H4 = Name_Based
+70:26:05 = Address_Based
+WF-SP700N = Name_Based
+48:D6:D5 = Address_Based
+Pixel Buds = Name_Based
+00:09:a7 = Address_Based
+Beoplay E8 = Name_Based
+2C:41:A1 = Address_Based
+Bose SoundWear = Name_Based
+2C:41:A1 = Address_Based
+Bose Free SoundSport = Name_Based
+00:18:09 = Address_Based
+Samsung Level On = Name_Based
+
#E0:D1:E6 = Address_Based
#00:18:6b = Address_Based
@@ -400,7 +422,7 @@
[INTEROP_DISABLE_PLAYER_APPLICATION_SETTING_CMDS]
00:09:93 = Address_Based
74:6f:f7 = Address_Based
-A0:56:B2 = Address_Based
+A0:56:B2:4F = Address_Based
00:54:AF = Address_Based
[INTEROP_DISABLE_CONNECTION_AFTER_COLLISION]
@@ -470,3 +492,8 @@
#Leviathan Mini :: 10:b7:f6:03:38:b0
[INTEROP_DISABLE_SNIFF_DURING_CALL]
10:b7:f6 = Address_Based
+
+#Nintendo Switch Pro Controller - does not set sniff interval dynamically.
+#Requires custom HID report command to change mode.
+[INTEROP_HID_HOST_LIMIT_SNIFF_INTERVAL]
+98:B6:E9 = Address_Based
diff --git a/system_bt_ext/device/src/interop.cc b/system_bt_ext/device/src/interop.cc
index 2381669..22cdab3 100644
--- a/system_bt_ext/device/src/interop.cc
+++ b/system_bt_ext/device/src/interop.cc
@@ -255,6 +255,7 @@
CASE_RETURN_STR(INTEROP_ADV_PBAP_VER_1_2)
CASE_RETURN_STR(INTEROP_DISABLE_SNIFF_LINK_DURING_SCO)
CASE_RETURN_STR(INTEROP_DISABLE_SNIFF_DURING_CALL)
+ CASE_RETURN_STR(INTEROP_HID_HOST_LIMIT_SNIFF_INTERVAL)
}
return "UNKNOWN";
}
diff --git a/system_bt_ext/device/src/profile_config.cc b/system_bt_ext/device/src/profile_config.cc
index a206fc8..39c95d7 100644
--- a/system_bt_ext/device/src/profile_config.cc
+++ b/system_bt_ext/device/src/profile_config.cc
@@ -283,7 +283,7 @@
max_pow_feature_t max_radiated_power_fetch(const profile_t profile, profile_info_t feature_name)
{
- static max_pow_feature_t Tech_max_power = {0xFF, 0xFF, 0xFF, false, false, false};
+ static max_pow_feature_t Tech_max_power = {0x80, 0x80, 0x80, false, false, false};
assert(profile);
LOG_WARN(LOG_TAG, "max_radiated_power_fetch:profile %d", profile);
diff --git a/vhal/include/hardware/vendor.h b/vhal/include/hardware/vendor.h
index ccddf2d..32668ab 100644
--- a/vhal/include/hardware/vendor.h
+++ b/vhal/include/hardware/vendor.h
@@ -53,6 +53,7 @@
#define ANDROID_INCLUDE_BT_VENDOR_H
#include <hardware/bluetooth.h>
+#include <vector>
__BEGIN_DECLS
@@ -120,6 +121,9 @@
uint16_t error_info, uint32_t event_mask, uint8_t lmp_ver, uint16_t lmp_subver,
uint16_t manufacturer_id, uint8_t power_level, int8_t rssi, uint8_t link_quality,
uint16_t glitch_count );
+typedef void (* btvendor_bqr_delivery_callback)(RawAddress* remote_bd_addr,
+ uint8_t lmp_ver, uint16_t lmp_subver, uint16_t manufacturer_id,
+ std::vector<uint8_t> bqr_raw_data);
typedef void (* btvendor_bredr_cleanup_callback)(bool status);
/** Callback to notify the remote device vendor properties.
@@ -147,6 +151,7 @@
size_t size;
btvendor_bredr_cleanup_callback bredr_cleanup_cb;
btvendor_iot_device_broadcast_callback iot_device_broadcast_cb;
+ btvendor_bqr_delivery_callback bqr_delivery_cb;
remote_dev_prop_callback rmt_dev_prop_cb;
hci_event_recv_callback hci_event_recv_cb;
adapter_vendor_prop_callback adapter_vendor_prop_cb;