Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

base: Add QTI bluetooth stack support #1

Merged
merged 58 commits into from
Jan 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
3873e58
Add BluetoothQualityReport class(1/2)
Jun 20, 2019
b0d40d2
BT: Adding aptX-Adaptive codec entry to Framework
Jul 6, 2018
e221e0e
TWS-A2DP: Add TWS+ codec to DevUI support
Oct 4, 2018
7b4f3ae
Bluetooth: Add SDK API support for TWS feature (2)
Mar 31, 2018
f65694d
Revert the change: AudioService: remove dead BT code.
Jun 19, 2019
30fd8ad
Bluetooth: Unpair both earbuds on unpair.
Apr 5, 2018
ebaa7cd
Bluetooth: Rename bluetooth property to support new P Treble rules
Jul 5, 2018
265c046
Bluetooth-TWS: Disable outgoing connection for 2nd earbud.
Aug 22, 2018
17e8358
Bluetooth-TWS: Disable outgoing connection to 2nd earbud
Oct 5, 2018
a34cd73
GAP: Reset bondingInitiatedLocally flag(1/3)
Jun 27, 2019
12e02e9
BT: Send info if call is CS type from telecomm service to BT apps.
Feb 22, 2016
cee035a
Bluetooth: TWSP: Support Battery Status information display
May 3, 2019
216ceaf
Add support for Transport discovery AD type (1/2)
Jun 24, 2018
db414b1
Support CALLBACK_TYPE_SENSOR_ROUTING
May 10, 2018
22f8e20
Add scan filter for Transport Discovery data
Mar 1, 2019
07af199
BLE: Add support for Group AD Type based scan filtering.
Sep 15, 2020
5c00015
Obex: Squashed commit of the following
Feb 1, 2018
59acc30
GAP: Handle the race condition cases in auto connect logic
Mar 2, 2020
381281c
Use BluetoothUtils instead of Utils
Aug 13, 2018
98877d1
audio: Add support for audio extended codecs
Mar 20, 2019
3b43632
audio: Add support for APTX TWSP audio codec
Apr 18, 2019
89c4336
TWS_A2DP: Handle active device change between TWS+ earbuds
May 9, 2019
c059458
BT_Audio: Updated Check for TWS+ switch
Jan 30, 2020
accc4de
BT: Add new intent to broadcast IOT device details
Sep 6, 2017
cd80715
Bluetooth: Fix for Global reference table overflow issue[1/2]
Nov 8, 2017
0cb8809
Keep the BluetoothHeadset finalize() method protected
Oct 4, 2018
b6d944b
BT Dev: Increase array size for codec selection in Dev Op
Sep 25, 2018
588c7e9
Bluetooth: Fix for out of bound exception
Jul 24, 2019
558bc9a
Keep a null check before accessing the BluetoothA2dpWrapper APIs.
Nov 6, 2018
9dade49
Enable codec change request when mode changes in aptX-adaptive
Aug 1, 2019
6dcc539
BT: Relocate A2DP codec strings for translation
moetayuko Jun 5, 2020
e5dfb71
Fix build errors
Jan 28, 2019
6380852
BLE: Fix NPE during start advertising
Aug 30, 2018
9c9304c
BT-Audio: Keep track of Active TWS+ EB device in BTHelper
Jul 3, 2020
4426dc4
Audio: Update current active bt device of mApmConnectedDevices.
Apr 2, 2020
fcdb667
Audio: use cached BT codec info during disconnecting
Feb 13, 2020
b40b4e3
Audio: Do not disconnect profiles till Bluetooth Off
Aug 28, 2019
4df8f7f
Add callback onA2dpCodecConfigChanged
Aug 9, 2020
852329e
Bluetooth: Add APTX-Adaptive and APTX-TWS+ entries.
Sep 16, 2020
f707521
Audio: Add support for lc3 codec.
Jul 20, 2020
1a94e72
Add LC3 codec type.
Oct 7, 2020
f172b0a
Periodic Advertisment Sync Transfer feature support
May 27, 2020
9c1d13b
base: BT build fixes
DennySPB Nov 12, 2021
3e11542
DeviceGroup: Framework changes for Group Device operations.
Jun 25, 2020
b03daaf
Add Broadcast profile id
Jan 11, 2021
294a866
Bluetooth: Ensure BLE/BT is turned on before Bonding.
Aug 16, 2021
b9f46f3
DeviceGroup: Frameworks changes (for dual mode devices).
Oct 22, 2020
fcdbde2
Bluetooth: Update Bluetooth permissions for internal APIS. (2/4)
Aug 24, 2021
82b9dbe
Use BLUETOOTH_CONNECT permission instead of legacy permission
Sep 24, 2021
a946a66
Bluetooth: Check AdapterService instance before getState.
Oct 12, 2021
9662cd5
Bluetooth: Add BC profile entry
Dec 23, 2020
5f9a51c
Group-UI: UI frameworks changes
Oct 29, 2020
00ceade
DeviceGroup: UI frameworks changes
Dec 3, 2020
a205efa
hfp: define STATE_AUDIO_DISCONNECTING audio state
Jan 31, 2020
5bf1135
Revert "Matching codec index between frameworks and stack"
Mar 31, 2021
f843877
A2dpSrc: Align legacy codec enumeration with AOSP(4/7)
May 13, 2020
6ee4399
Bluetooth: Add constructor for sending address type
Dec 10, 2020
17a3be2
audio: Discard QTI only codecs when AOSP BT stack is in use
luk1337 Dec 28, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 197 additions & 1 deletion core/java/android/bluetooth/BluetoothAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@
import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
* Represents the local device Bluetooth adapter. The {@link BluetoothAdapter}
Expand Down Expand Up @@ -1054,7 +1057,10 @@ public boolean enableBLE() {
@SuppressLint("AndroidFrameworkRequiresPermission")
protected Integer recompute(Void query) {
try {
return mService.getState();
if (mService != null) {
return mService.getState();
}
return BluetoothAdapter.STATE_OFF;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
Expand Down Expand Up @@ -2004,6 +2010,21 @@ public boolean setActiveDevice(@NonNull BluetoothDevice device,
return false;
}

/** @hide */
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean isBroadcastActive() {
try {
mServiceLock.readLock().lock();
if (mService != null) {
return mService.isBroadcastActive(mAttributionSource);
}
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
}
return false;
}
/**
* Connects all enabled and supported bluetooth profiles between the local and remote device.
* Connection is asynchronous and you should listen to each profile's broadcast intent
Expand Down Expand Up @@ -2987,6 +3008,92 @@ public Pair<byte[], byte[]> readOutOfBandData() {
return null;
}

private void closeBCProfile(BluetoothProfile proxy) {
Class<?> bshClass = null;
Method bshClose = null;
try {
bshClass = Class.forName("android.bluetooth.BluetoothSyncHelper");
} catch (ClassNotFoundException ex) {
Log.e(TAG, "no BSH: exists");
bshClass = null;
}
if (bshClass != null) {
Log.d(TAG, "Able to get BSH class handle");
try {
bshClose = bshClass.getDeclaredMethod("close", null);
} catch (NoSuchMethodException e) {
Log.e(TAG, "no BSH:isSupported method exists");
}
if (bshClose != null) {
try {
bshClose.invoke(proxy, null);
} catch(IllegalAccessException e) {
Log.e(TAG, "bshClose IllegalAccessException");
} catch (InvocationTargetException e) {
Log.e(TAG, "bshClose InvocationTargetException");
}
}
}
Log.d(TAG, "CloseBCProfile returns");
}

private boolean getBCProfile(Context context, BluetoothProfile.ServiceListener sl) {
boolean ret = true;
boolean isProfileSupported = false;
Class<?> bshClass = null;
Method bshSupported = null;
Constructor bshCons = null;
Object bshObj = null;
try {
bshClass = Class.forName("android.bluetooth.BluetoothSyncHelper");
} catch (ClassNotFoundException ex) {
Log.e(TAG, "no BSH: exists");
bshClass = null;
}
if (bshClass != null) {
Log.d(TAG, "Able to get BSH class handle");
try {
bshSupported = bshClass.getDeclaredMethod("isSupported", null);
} catch (NoSuchMethodException e) {
Log.e(TAG, "no BSH:isSupported method exists: gdm");
}
try {
bshCons =
bshClass.getDeclaredConstructor(
new Class[]{Context.class,
BluetoothProfile.ServiceListener.class});
} catch (NoSuchMethodException ex) {
Log.e(TAG, "bshCons: NoSuchMethodException: gdm" + ex);
}
}
if (bshClass != null && bshSupported != null && bshCons != null) {
try {
isProfileSupported = (boolean)bshSupported.invoke(null, null);
} catch(IllegalAccessException e) {
Log.e(TAG, "BSH:isSupported IllegalAccessException");
} catch (InvocationTargetException e) {
Log.e(TAG, "BSH:isSupported InvocationTargetException");
}
if (isProfileSupported) {
try {
bshObj = bshCons.newInstance(
context, sl);
} catch (InstantiationException ex) {
Log.e(TAG, "bshCons InstantiationException:" + ex);
} catch (IllegalAccessException ex) {
Log.e(TAG, "bshCons InstantiationException:" + ex);
} catch (InvocationTargetException ex) {
Log.e(TAG, "bshCons InvocationTargetException:" + ex);
}
}
}
if (bshObj == null) {
ret = false;
}
Log.d(TAG, "getBCService returns" + ret);
return ret;
}

/**
* Get the profile proxy object associated with the profile.
*
Expand Down Expand Up @@ -3056,6 +3163,10 @@ public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener
} else if (profile == BluetoothProfile.HID_DEVICE) {
BluetoothHidDevice hidDevice = new BluetoothHidDevice(context, listener, this);
return true;
} else if (profile == BluetoothProfile.BROADCAST) {
return getBroadcastProfile(context, listener);
} else if (profile == BluetoothProfile.BC_PROFILE) {
return getBCProfile(context, listener);
} else if (profile == BluetoothProfile.HEARING_AID) {
if (isHearingAidProfileSupported()) {
BluetoothHearingAid hearingAid = new BluetoothHearingAid(context, listener, this);
Expand All @@ -3065,6 +3176,9 @@ public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener
} else if (profile == BluetoothProfile.LE_AUDIO) {
BluetoothLeAudio leAudio = new BluetoothLeAudio(context, listener, this);
return true;
} else if (profile == BluetoothProfile.GROUP_CLIENT) {
BluetoothDeviceGroup groupClient = new BluetoothDeviceGroup(context, listener);
return true;
} else {
return false;
}
Expand Down Expand Up @@ -3150,16 +3264,82 @@ public void closeProfileProxy(int profile, BluetoothProfile proxy) {
BluetoothHidDevice hidDevice = (BluetoothHidDevice) proxy;
hidDevice.close();
break;
case BluetoothProfile.BROADCAST:
closeBroadcastProfile(proxy);
case BluetoothProfile.BC_PROFILE:
closeBCProfile(proxy);
break;
case BluetoothProfile.HEARING_AID:
BluetoothHearingAid hearingAid = (BluetoothHearingAid) proxy;
hearingAid.close();
break;
case BluetoothProfile.LE_AUDIO:
BluetoothLeAudio leAudio = (BluetoothLeAudio) proxy;
leAudio.close();
break;
case BluetoothProfile.GROUP_CLIENT:
BluetoothDeviceGroup groupClient = (BluetoothDeviceGroup) proxy;
groupClient.close();
break;
}
}

private boolean getBroadcastProfile(Context context,
BluetoothProfile.ServiceListener listener) {
boolean ret = true;
Class<?> broadcastClass = null;
Constructor bcastConstructor = null;
Object broadcastObj = null;
try {
broadcastClass = Class.forName("android.bluetooth.BluetoothBroadcast");
} catch (ClassNotFoundException ex) {
Log.e(TAG, "no BluetoothBroadcast: exists");
}
if (broadcastClass != null) {
try {
bcastConstructor =
broadcastClass.getDeclaredConstructor(new Class[]{Context.class,
BluetoothProfile.ServiceListener.class});
} catch (NoSuchMethodException ex) {
Log.e(TAG, "bcastConstructor: NoSuchMethodException: gdm" + ex);
}
}
if (bcastConstructor != null) {
try {
broadcastObj = bcastConstructor.newInstance(context, listener);
} catch (InstantiationException | IllegalAccessException |
InvocationTargetException ex) {
ex.printStackTrace();
}
}
if (broadcastObj == null) {
return false;
}
return true;
}
private void closeBroadcastProfile(BluetoothProfile proxy) {
Class<?> broadcastClass = null;
Method broadcastClose = null;
try {
broadcastClass = Class.forName("android.bluetooth.BluetootBroadcast");
} catch (ClassNotFoundException ex) {
Log.e(TAG, "no BluetoothBroadcast: exists");
}
if (broadcastClass != null) {
try {
broadcastClose = broadcastClass.getDeclaredMethod("close", null);
} catch (NoSuchMethodException e) {
Log.e(TAG, "no Broadcast:close method exists");
}
if (broadcastClose != null) {
try {
broadcastClose.invoke(proxy, null);
} catch(IllegalAccessException | InvocationTargetException ex) {
ex.printStackTrace();
}
}
}
}
private static final IBluetoothManagerCallback sManagerCallback =
new IBluetoothManagerCallback.Stub() {
public void onBluetoothServiceUp(IBluetooth bluetoothService) {
Expand Down Expand Up @@ -3497,6 +3677,22 @@ public void onBluetoothStateChange(boolean on) {
}
}

/**
* @hide
*/
public void unregisterAdapter() {
try {
//mServiceLock.writeLock().lock();
if (mManagerService != null){
mManagerService.unregisterAdapter(mManagerCallback);
}
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
//mServiceLock.writeLock().unlock();
}
}

private Set<BluetoothDevice> toDeviceSet(List<BluetoothDevice> devices) {
Set<BluetoothDevice> deviceSet = new HashSet<BluetoothDevice>(devices);
return Collections.unmodifiableSet(deviceSet);
Expand Down
5 changes: 5 additions & 0 deletions core/java/android/bluetooth/BluetoothClass.java
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ public static final class Service {
private static final int BITMASK = 0xFFE000;

public static final int LIMITED_DISCOVERABILITY = 0x002000;
/**
* @hide
*/
public static final int GROUP = 0x004000;

public static final int POSITIONING = 0x010000;
public static final int NETWORKING = 0x020000;
public static final int RENDER = 0x040000;
Expand Down
44 changes: 43 additions & 1 deletion core/java/android/bluetooth/BluetoothCodecConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ public final class BluetoothCodecConfig implements Parcelable {
SOURCE_CODEC_TYPE_APTX,
SOURCE_CODEC_TYPE_APTX_HD,
SOURCE_CODEC_TYPE_LDAC,
SOURCE_CODEC_TYPE_MAX,
SOURCE_CODEC_TYPE_APTX_ADAPTIVE,
SOURCE_CODEC_TYPE_APTX_TWSP,
SOURCE_QVA_CODEC_TYPE_MAX,
SOURCE_CODEC_TYPE_INVALID
})
@Retention(RetentionPolicy.SOURCE)
Expand All @@ -70,6 +72,24 @@ public final class BluetoothCodecConfig implements Parcelable {
@UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_MAX = 5;

@UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_APTX_ADAPTIVE = SOURCE_CODEC_TYPE_MAX;

@UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_APTX_TWSP = SOURCE_CODEC_TYPE_MAX + 1;

@UnsupportedAppUsage
public static final int SOURCE_QVA_CODEC_TYPE_MAX = SOURCE_CODEC_TYPE_MAX + 2;

/* CELT is not an A2DP Codec and only used to fetch encoder
** format for BA usecase, moving out of a2dp codec value list
*/
@UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_CELT = 8;

@UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_LC3 = 9;

@UnsupportedAppUsage
public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;

Expand Down Expand Up @@ -126,6 +146,17 @@ public final class BluetoothCodecConfig implements Parcelable {
@UnsupportedAppUsage
public static final int SAMPLE_RATE_192000 = 0x1 << 5;

@UnsupportedAppUsage
public static final int SAMPLE_RATE_16000 = 0x1 << 6;

@UnsupportedAppUsage
public static final int SAMPLE_RATE_24000 = 0x1 << 7;

@UnsupportedAppUsage
public static final int SAMPLE_RATE_32000 = 0x1 << 8;

@UnsupportedAppUsage
public static final int SAMPLE_RATE_8000 = 0x1 << 9;

/** @hide */
@IntDef(prefix = "BITS_PER_SAMPLE_", value = {
Expand Down Expand Up @@ -168,6 +199,9 @@ public final class BluetoothCodecConfig implements Parcelable {
@UnsupportedAppUsage
public static final int CHANNEL_MODE_STEREO = 0x1 << 1;

@UnsupportedAppUsage
public static final int CHANNEL_MODE_JOINT_STEREO = 0x1 << 2;

private final @SourceCodecType int mCodecType;
private @CodecPriority int mCodecPriority;
private final @SampleRate int mSampleRate;
Expand Down Expand Up @@ -403,6 +437,10 @@ public void writeToParcel(Parcel out, int flags) {
return "aptX HD";
case SOURCE_CODEC_TYPE_LDAC:
return "LDAC";
case SOURCE_CODEC_TYPE_APTX_ADAPTIVE:
return "aptX Adaptive";
case SOURCE_CODEC_TYPE_APTX_TWSP:
return "aptX TWS+";
case SOURCE_CODEC_TYPE_INVALID:
return "INVALID CODEC";
default:
Expand Down Expand Up @@ -652,6 +690,10 @@ public boolean sameCodecSpecificParameters(BluetoothCodecConfig other) {
if (mCodecSpecific1 != other.mCodecSpecific1) {
return false;
}
case SOURCE_CODEC_TYPE_APTX_ADAPTIVE:
if (other.mCodecSpecific4 > 0) {
return false;
}
// fall through
default:
return true;
Expand Down
Loading