summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/app/jni/com_android_bluetooth_le_audio.cpp21
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterService.java17
-rw-r--r--android/app/src/com/android/bluetooth/gatt/GattService.java18
-rw-r--r--android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java15
-rw-r--r--android/app/src/com/android/bluetooth/le_audio/LeAudioService.java64
-rw-r--r--android/app/src/com/android/bluetooth/mcp/McpService.java76
-rw-r--r--framework/api/current.txt40
-rw-r--r--framework/api/system-current.txt16
-rw-r--r--framework/java/android/bluetooth/BluetoothA2dp.java56
-rw-r--r--framework/java/android/bluetooth/BluetoothAdapter.java81
-rw-r--r--framework/java/android/bluetooth/BluetoothCodecConfig.java8
-rw-r--r--framework/java/android/bluetooth/BluetoothDevice.java38
-rw-r--r--framework/java/android/bluetooth/BluetoothDevicePicker.java22
-rw-r--r--framework/java/android/bluetooth/BluetoothLeAudio.java49
-rw-r--r--framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java161
-rw-r--r--framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java194
-rw-r--r--system/binder/Android.bp1
-rw-r--r--system/binder/android/bluetooth/IBluetooth.aidl3
-rw-r--r--system/binder/android/bluetooth/IBluetoothActivityEnergyInfoListener.aidl34
-rw-r--r--system/binder/android/bluetooth/IBluetoothLeAudio.aidl4
-rw-r--r--system/bta/dm/bta_dm_act.cc2
-rw-r--r--system/bta/include/bta_api.h2
-rw-r--r--system/bta/le_audio/state_machine_test.cc2
-rw-r--r--system/main/Android.bp2
-rw-r--r--system/main/shim/btm_api.cc7
-rw-r--r--system/main/shim/btm_api.h15
-rw-r--r--system/main/shim/le_advertising_manager.cc4
-rw-r--r--system/test/mock/mock_main_shim_btm_api.cc4
-rw-r--r--system/test/mock/mock_stack_btm.cc3
-rw-r--r--system/test/mock/mock_stack_btm_inq.cc4
30 files changed, 704 insertions, 259 deletions
diff --git a/android/app/jni/com_android_bluetooth_le_audio.cpp b/android/app/jni/com_android_bluetooth_le_audio.cpp
index 0e61a80c4e..ea435c77c0 100644
--- a/android/app/jni/com_android_bluetooth_le_audio.cpp
+++ b/android/app/jni/com_android_bluetooth_le_audio.cpp
@@ -158,7 +158,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
jclass jniBluetoothLeAudioCodecConfigClass =
env->FindClass("android/bluetooth/BluetoothLeAudioCodecConfig");
android_bluetooth_BluetoothLeAudioCodecConfig.constructor = env->GetMethodID(
- jniBluetoothLeAudioCodecConfigClass, "<init>", "(IIIIIII)V");
+ jniBluetoothLeAudioCodecConfigClass, "<init>", "(IIIIIIIII)V");
android_bluetooth_BluetoothLeAudioCodecConfig.getCodecType = env->GetMethodID(
jniBluetoothLeAudioCodecConfigClass, "getCodecType", "()I");
@@ -355,6 +355,21 @@ static void groupSetActiveNative(JNIEnv* env, jobject object, jint group_id) {
sLeAudioClientInterface->GroupSetActive(group_id);
}
+static void setCodecConfigPreferenceNative(JNIEnv* env, jobject object,
+ jint group_id,
+ jobject inputCodecConfig,
+ jobject outputCodecConfig) {
+ if (!env->IsInstanceOf(inputCodecConfig,
+ android_bluetooth_BluetoothLeAudioCodecConfig.clazz) ||
+ !env->IsInstanceOf(outputCodecConfig,
+ android_bluetooth_BluetoothLeAudioCodecConfig.clazz)) {
+ ALOGE("%s: Invalid BluetoothLeAudioCodecConfig instance", __func__);
+ return;
+ }
+
+ // TODO Implement
+}
+
static JNINativeMethod sMethods[] = {
{"classInitNative", "()V", (void*)classInitNative},
{"initNative", "([Landroid/bluetooth/BluetoothLeAudioCodecConfig;)V",
@@ -365,6 +380,10 @@ static JNINativeMethod sMethods[] = {
{"groupAddNodeNative", "(I[B)Z", (void*)groupAddNodeNative},
{"groupRemoveNodeNative", "(I[B)Z", (void*)groupRemoveNodeNative},
{"groupSetActiveNative", "(I)V", (void*)groupSetActiveNative},
+ {"setCodecConfigPreferenceNative",
+ "(ILandroid/bluetooth/BluetoothLeAudioCodecConfig;Landroid/bluetooth/"
+ "BluetoothLeAudioCodecConfig;)V",
+ (void*)setCodecConfigPreferenceNative},
};
/* Le Audio Broadcaster */
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
index 1a5e7a5a73..fe3209c120 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
@@ -55,6 +55,7 @@ import android.bluetooth.BluetoothStatusCodes;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.BufferConstraints;
import android.bluetooth.IBluetooth;
+import android.bluetooth.IBluetoothActivityEnergyInfoListener;
import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothConnectionCallback;
import android.bluetooth.IBluetoothMetadataListener;
@@ -84,7 +85,6 @@ import android.os.ParcelUuid;
import android.os.PowerManager;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
-import android.os.ResultReceiver;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
@@ -217,8 +217,6 @@ public class AdapterService extends Service {
public static final String ACTIVITY_ATTRIBUTION_NO_ACTIVE_DEVICE_ADDRESS =
"no_active_device_address";
- public static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";
-
// Report ID definition
public enum BqrQualityReportId {
QUALITY_REPORT_ID_MONITOR_MODE(0x01),
@@ -3600,11 +3598,14 @@ public class AdapterService extends Service {
}
@Override
- public void requestActivityInfo(ResultReceiver result, AttributionSource source) {
- Bundle bundle = new Bundle();
- bundle.putParcelable(RESULT_RECEIVER_CONTROLLER_KEY,
- reportActivityInfo(source));
- result.send(0, bundle);
+ public void requestActivityInfo(IBluetoothActivityEnergyInfoListener listener,
+ AttributionSource source) {
+ BluetoothActivityEnergyInfo info = reportActivityInfo(source);
+ try {
+ listener.onBluetoothActivityEnergyInfo(info);
+ } catch (RemoteException e) {
+ Log.e(TAG, "onBluetoothActivityEnergyInfo: RemoteException", e);
+ }
}
@Override
diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java
index 6967511700..1df37713eb 100644
--- a/android/app/src/com/android/bluetooth/gatt/GattService.java
+++ b/android/app/src/com/android/bluetooth/gatt/GattService.java
@@ -1776,7 +1776,9 @@ public class GattService extends ProfileService {
for (ScanClient client : mScanManager.getRegularScanQueue()) {
ScannerMap.App app = mScannerMap.getById(client.scannerId);
if (app == null) {
- Log.i(TAG, "App is null; skip.");
+ if (VDBG) {
+ Log.d(TAG, "App is null; skip.");
+ }
continue;
}
@@ -1788,7 +1790,9 @@ public class GattService extends ProfileService {
if (settings.getLegacy()) {
if ((eventType & ET_LEGACY_MASK) == 0) {
// If this is legacy scan, but nonlegacy result - skip.
- Log.i(TAG, "Legacy scan, non legacy result; skip.");
+ if (VDBG) {
+ Log.d(TAG, "Legacy scan, non legacy result; skip.");
+ }
continue;
} else {
// Some apps are used to fixed-size advertise data.
@@ -1829,8 +1833,10 @@ public class GattService extends ProfileService {
}
MatchResult matchResult = matchesFilters(client, result, originalAddress);
if (!hasPermission || !matchResult.getMatches()) {
- Log.i(TAG, "Skipping client: permission="
- + hasPermission + " matches=" + matchResult.getMatches());
+ if (VDBG) {
+ Log.d(TAG, "Skipping client: permission="
+ + hasPermission + " matches=" + matchResult.getMatches());
+ }
continue;
}
@@ -1842,7 +1848,9 @@ public class GattService extends ProfileService {
}
if ((settings.getCallbackType() & ScanSettings.CALLBACK_TYPE_ALL_MATCHES) == 0) {
- Log.i(TAG, "Skipping client: CALLBACK_TYPE_ALL_MATCHES");
+ if (VDBG) {
+ Log.d(TAG, "Skipping client: CALLBACK_TYPE_ALL_MATCHES");
+ }
continue;
}
diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java
index 46e2db2202..6dfc627f83 100644
--- a/android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java
@@ -215,6 +215,18 @@ public class LeAudioNativeInterface {
groupSetActiveNative(groupId);
}
+ /**
+ * Set codec config preference.
+ * @param groupId group ID for the preference
+ * @param inputCodecConfig input codec configuration
+ * @param outputCodecConfig output codec configuration
+ */
+ public void setCodecConfigPreference(int groupId,
+ BluetoothLeAudioCodecConfig inputCodecConfig,
+ BluetoothLeAudioCodecConfig outputCodecConfig) {
+ setCodecConfigPreferenceNative(groupId, inputCodecConfig, outputCodecConfig);
+ }
+
// Native methods that call into the JNI interface
private static native void classInitNative();
private native void initNative(BluetoothLeAudioCodecConfig[] codecConfigOffloading);
@@ -224,4 +236,7 @@ public class LeAudioNativeInterface {
private native boolean groupAddNodeNative(int groupId, byte[] address);
private native boolean groupRemoveNodeNative(int groupId, byte[] address);
private native void groupSetActiveNative(int groupId);
+ private native void setCodecConfigPreferenceNative(int groupId,
+ BluetoothLeAudioCodecConfig inputCodecConfig,
+ BluetoothLeAudioCodecConfig outputCodecConfig);
}
diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
index e6fc534de5..5e1834efff 100644
--- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
@@ -132,11 +132,13 @@ public class LeAudioService extends ProfileService {
mIsConnected = false;
mIsActive = false;
mActiveContexts = ACTIVE_CONTEXTS_NONE;
+ mCodecStatus = null;
}
public Boolean mIsConnected;
public Boolean mIsActive;
public Integer mActiveContexts;
+ public BluetoothLeAudioCodecStatus mCodecStatus;
}
private final Map<Integer, LeAudioGroupDescriptor> mGroupDescriptors = new LinkedHashMap<>();
@@ -1726,46 +1728,64 @@ public class LeAudioService extends ProfileService {
/**
* Gets the current codec status (configuration and capability).
*
- * @param device the remote Bluetooth device.
+ * @param groupId the group id
* @return the current codec status
* @hide
*/
- public BluetoothLeAudioCodecStatus getCodecStatus(BluetoothDevice device) {
+ public BluetoothLeAudioCodecStatus getCodecStatus(int groupId) {
if (DBG) {
- Log.d(TAG, "getCodecStatus(" + device + ")");
+ Log.d(TAG, "getCodecStatus(" + groupId + ")");
+ }
+ LeAudioGroupDescriptor descriptor = mGroupDescriptors.get(groupId);
+ if (descriptor != null) {
+ return descriptor.mCodecStatus;
}
-
return null;
}
/**
* Sets the codec configuration preference.
*
- * @param device the remote Bluetooth device.
- * @param codecConfig the codec configuration preference
+ * @param groupId the group id
+ * @param inputCodecConfig the input codec configuration preference
+ * @param outputCodecConfig the output codec configuration preference
* @hide
*/
- public void setCodecConfigPreference(BluetoothDevice device,
- BluetoothLeAudioCodecConfig codecConfig) {
+ public void setCodecConfigPreference(int groupId,
+ BluetoothLeAudioCodecConfig inputCodecConfig,
+ BluetoothLeAudioCodecConfig outputCodecConfig) {
if (DBG) {
- Log.d(TAG, "setCodecConfigPreference(" + device + "): "
- + Objects.toString(codecConfig));
+ Log.d(TAG, "setCodecConfigPreference(" + groupId + "): "
+ + Objects.toString(inputCodecConfig)
+ + Objects.toString(outputCodecConfig));
}
- if (device == null) {
- Log.e(TAG, "setCodecConfigPreference: Invalid device");
+ LeAudioGroupDescriptor descriptor = mGroupDescriptors.get(groupId);
+ if (descriptor == null) {
+ Log.e(TAG, "setCodecConfigPreference: Invalid groupId, " + groupId);
return;
}
- if (codecConfig == null) {
+
+ if (inputCodecConfig == null || outputCodecConfig == null) {
Log.e(TAG, "setCodecConfigPreference: Codec config can't be null");
return;
}
- BluetoothLeAudioCodecStatus codecStatus = getCodecStatus(device);
- if (codecStatus == null) {
+
+ /* We support different configuration for input and output but codec type
+ * shall be same */
+ if (inputCodecConfig.getCodecType() != outputCodecConfig.getCodecType()) {
+ Log.e(TAG, "setCodecConfigPreference: Input codec type: "
+ + inputCodecConfig.getCodecType()
+ + "does not match output codec type: " + outputCodecConfig.getCodecType());
+ return;
+ }
+
+ if (descriptor.mCodecStatus == null) {
Log.e(TAG, "setCodecConfigPreference: Codec status is null");
return;
}
- // TODO: pass the information to bt stack
+ mLeAudioNativeInterface.setCodecConfigPreference(groupId,
+ inputCodecConfig, outputCodecConfig);
}
@@ -2185,14 +2205,14 @@ public class LeAudioService extends ProfileService {
}
@Override
- public void getCodecStatus(BluetoothDevice device,
+ public void getCodecStatus(int groupId,
AttributionSource source, SynchronousResultReceiver receiver) {
try {
LeAudioService service = getService(source);
BluetoothLeAudioCodecStatus codecStatus = null;
if (service != null) {
enforceBluetoothPrivilegedPermission(service);
- codecStatus = service.getCodecStatus(device);
+ codecStatus = service.getCodecStatus(groupId);
}
receiver.send(codecStatus);
} catch (RuntimeException e) {
@@ -2201,15 +2221,17 @@ public class LeAudioService extends ProfileService {
}
@Override
- public void setCodecConfigPreference(BluetoothDevice device,
- BluetoothLeAudioCodecConfig codecConfig, AttributionSource source) {
+ public void setCodecConfigPreference(int groupId,
+ BluetoothLeAudioCodecConfig inputCodecConfig,
+ BluetoothLeAudioCodecConfig outputCodecConfig,
+ AttributionSource source) {
LeAudioService service = getService(source);
if (service == null) {
return;
}
enforceBluetoothPrivilegedPermission(service);
- service.setCodecConfigPreference(device, codecConfig);
+ service.setCodecConfigPreference(groupId, inputCodecConfig, outputCodecConfig);
}
}
diff --git a/android/app/src/com/android/bluetooth/mcp/McpService.java b/android/app/src/com/android/bluetooth/mcp/McpService.java
index 2508b2f38f..34f413882c 100644
--- a/android/app/src/com/android/bluetooth/mcp/McpService.java
+++ b/android/app/src/com/android/bluetooth/mcp/McpService.java
@@ -26,6 +26,7 @@ import android.util.Log;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.ProfileService;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import java.util.HashMap;
@@ -41,8 +42,11 @@ public class McpService extends ProfileService {
private static final String TAG = "BluetoothMcpService";
private static McpService sMcpService;
+ private static MediaControlProfile sGmcsForTesting;
- private static MediaControlProfile sGmcs;
+ private Object mLock = new Object();
+ @GuardedBy("mLock")
+ private MediaControlProfile mGmcs;
private Map<BluetoothDevice, Integer> mDeviceAuthorizations = new HashMap<>();
private Handler mHandler = new Handler(Looper.getMainLooper());
@@ -68,11 +72,12 @@ public class McpService extends ProfileService {
@VisibleForTesting
public static MediaControlProfile getMediaControlProfile() {
- return sGmcs;
+ return sGmcsForTesting;
}
+ @VisibleForTesting
public static void setMediaControlProfileForTesting(MediaControlProfile mediaControlProfile) {
- sGmcs = mediaControlProfile;
+ sGmcsForTesting = mediaControlProfile;
}
@Override
@@ -100,11 +105,19 @@ public class McpService extends ProfileService {
// Mark service as started
setMcpService(this);
- if (sGmcs == null) {
- // Initialize the Media Control Service Server
- sGmcs = new MediaControlProfile(this);
- // Requires this service to be already started thus we have to make it an async call
- mHandler.post(() -> sGmcs.init());
+ synchronized (mLock) {
+ if (getGmcsLocked() == null) {
+ // Initialize the Media Control Service Server
+ mGmcs = new MediaControlProfile(this);
+ // Requires this service to be already started thus we have to make it an async call
+ mHandler.post(() -> {
+ synchronized (mLock) {
+ if (mGmcs != null) {
+ mGmcs.init();
+ }
+ }
+ });
+ }
}
return true;
@@ -121,9 +134,17 @@ public class McpService extends ProfileService {
return true;
}
- if (sGmcs != null) {
- sGmcs.cleanup();
- sGmcs = null;
+ synchronized (mLock) {
+ // A runnable for calling mGmcs.init() could be pending on mHandler
+ mHandler.removeCallbacksAndMessages(null);
+ if (mGmcs != null) {
+ mGmcs.cleanup();
+ mGmcs = null;
+ }
+ if (sGmcsForTesting != null) {
+ sGmcsForTesting.cleanup();
+ sGmcsForTesting = null;
+ }
}
// Mark service as stopped
@@ -138,6 +159,17 @@ public class McpService extends ProfileService {
}
}
+ @Override
+ public void dump(StringBuilder sb) {
+ super.dump(sb);
+ synchronized (mLock) {
+ MediaControlProfile gmcs = getGmcsLocked();
+ if (gmcs != null) {
+ gmcs.dump(sb);
+ }
+ }
+ }
+
public void onDeviceUnauthorized(BluetoothDevice device) {
Log.w(TAG, "onDeviceUnauthorized - authorization notification not implemented yet ");
}
@@ -148,7 +180,12 @@ public class McpService extends ProfileService {
: BluetoothDevice.ACCESS_REJECTED;
mDeviceAuthorizations.put(device, authorization);
- sGmcs.onDeviceAuthorizationSet(device);
+ synchronized (mLock) {
+ MediaControlProfile gmcs = getGmcsLocked();
+ if (gmcs != null) {
+ gmcs.onDeviceAuthorizationSet(device);
+ }
+ }
}
public int getDeviceAuthorization(BluetoothDevice device) {
@@ -157,6 +194,15 @@ public class McpService extends ProfileService {
return mDeviceAuthorizations.getOrDefault(device, BluetoothDevice.ACCESS_UNKNOWN);
}
+ @GuardedBy("mLock")
+ private MediaControlProfile getGmcsLocked() {
+ if (sGmcsForTesting != null) {
+ return sGmcsForTesting;
+ } else {
+ return mGmcs;
+ }
+ }
+
/**
* Binder object: must be a static class or memory leak may occur
*/
@@ -195,10 +241,4 @@ public class McpService extends ProfileService {
mService = null;
}
}
-
- @Override
- public void dump(StringBuilder sb) {
- super.dump(sb);
- sGmcs.dump(sb);
- }
}
diff --git a/framework/api/current.txt b/framework/api/current.txt
index b2dc4367f1..cf4c4b18f6 100644
--- a/framework/api/current.txt
+++ b/framework/api/current.txt
@@ -930,21 +930,23 @@ package android.bluetooth {
public final class BluetoothLeAudioCodecConfig implements android.os.Parcelable {
method public int describeContents();
method public int getBitsPerSample();
- method public int getChannelMode();
+ method public int getChannelCount();
method @NonNull public String getCodecName();
method public int getCodecPriority();
method public int getCodecType();
method public int getFrameDuration();
+ method public int getMaxOctetsPerFrame();
+ method public int getMinOctetsPerFrame();
method public int getOctetsPerFrame();
method public int getSampleRate();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field public static final int BITS_PER_SAMPLE_16 = 1; // 0x1
field public static final int BITS_PER_SAMPLE_24 = 2; // 0x2
- field public static final int BITS_PER_SAMPLE_32 = 3; // 0x3
+ field public static final int BITS_PER_SAMPLE_32 = 8; // 0x8
field public static final int BITS_PER_SAMPLE_NONE = 0; // 0x0
- field public static final int CHANNEL_MODE_MONO = 1; // 0x1
- field public static final int CHANNEL_MODE_NONE = 0; // 0x0
- field public static final int CHANNEL_MODE_STEREO = 2; // 0x2
+ field public static final int CHANNEL_COUNT_1 = 1; // 0x1
+ field public static final int CHANNEL_COUNT_2 = 2; // 0x2
+ field public static final int CHANNEL_COUNT_NONE = 0; // 0x0
field public static final int CODEC_PRIORITY_DEFAULT = 0; // 0x0
field public static final int CODEC_PRIORITY_DISABLED = -1; // 0xffffffff
field public static final int CODEC_PRIORITY_HIGHEST = 1000000; // 0xf4240
@@ -952,11 +954,11 @@ package android.bluetooth {
field public static final int FRAME_DURATION_10000 = 2; // 0x2
field public static final int FRAME_DURATION_7500 = 1; // 0x1
field public static final int FRAME_DURATION_NONE = 0; // 0x0
- field public static final int SAMPLE_RATE_16000 = 2; // 0x2
- field public static final int SAMPLE_RATE_24000 = 3; // 0x3
- field public static final int SAMPLE_RATE_32000 = 4; // 0x4
- field public static final int SAMPLE_RATE_44100 = 5; // 0x5
- field public static final int SAMPLE_RATE_48000 = 6; // 0x6
+ field public static final int SAMPLE_RATE_16000 = 4; // 0x4
+ field public static final int SAMPLE_RATE_24000 = 16; // 0x10
+ field public static final int SAMPLE_RATE_32000 = 32; // 0x20
+ field public static final int SAMPLE_RATE_44100 = 64; // 0x40
+ field public static final int SAMPLE_RATE_48000 = 128; // 0x80
field public static final int SAMPLE_RATE_8000 = 1; // 0x1
field public static final int SAMPLE_RATE_NONE = 0; // 0x0
field public static final int SOURCE_CODEC_TYPE_INVALID = 1000000; // 0xf4240
@@ -968,21 +970,27 @@ package android.bluetooth {
ctor public BluetoothLeAudioCodecConfig.Builder(@NonNull android.bluetooth.BluetoothLeAudioCodecConfig);
method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig build();
method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setBitsPerSample(int);
- method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setChannelMode(int);
+ method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setChannelCount(int);
method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setCodecPriority(int);
method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setCodecType(int);
method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setFrameDuration(int);
+ method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setMaxOctetsPerFrame(int);
+ method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setMinOctetsPerFrame(int);
method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setOctetsPerFrame(int);
method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setSampleRate(int);
}
public final class BluetoothLeAudioCodecStatus implements android.os.Parcelable {
- ctor public BluetoothLeAudioCodecStatus(@Nullable android.bluetooth.BluetoothLeAudioCodecConfig, @NonNull java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig>, @NonNull java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig>);
+ ctor public BluetoothLeAudioCodecStatus(@Nullable android.bluetooth.BluetoothLeAudioCodecConfig, @Nullable android.bluetooth.BluetoothLeAudioCodecConfig, @NonNull java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig>, @NonNull java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig>, @NonNull java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig>, @NonNull java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig>);
method public int describeContents();
- method @Nullable public android.bluetooth.BluetoothLeAudioCodecConfig getCodecConfig();
- method @NonNull public java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig> getCodecLocalCapabilities();
- method @NonNull public java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig> getCodecSelectableCapabilities();
- method public boolean isCodecConfigSelectable(@Nullable android.bluetooth.BluetoothLeAudioCodecConfig);
+ method @Nullable public android.bluetooth.BluetoothLeAudioCodecConfig getInputCodecConfig();
+ method @NonNull public java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig> getInputCodecLocalCapabilities();
+ method @NonNull public java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig> getInputCodecSelectableCapabilities();
+ method @Nullable public android.bluetooth.BluetoothLeAudioCodecConfig getOutputCodecConfig();
+ method @NonNull public java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig> getOutputCodecLocalCapabilities();
+ method @NonNull public java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig> getOutputCodecSelectableCapabilities();
+ method public boolean isInputCodecConfigSelectable(@Nullable android.bluetooth.BluetoothLeAudioCodecConfig);
+ method public boolean isOutputCodecConfigSelectable(@Nullable android.bluetooth.BluetoothLeAudioCodecConfig);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothLeAudioCodecStatus> CREATOR;
field public static final String EXTRA_LE_AUDIO_CODEC_STATUS = "android.bluetooth.extra.LE_AUDIO_CODEC_STATUS";
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index e29699beed..d5cb46c4f3 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -65,14 +65,14 @@ package android.bluetooth {
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public long getDiscoveryEndMillis();
method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getMostRecentlyConnectedDevices();
method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<java.lang.Integer> getSupportedProfiles();
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.os.ParcelUuid[] getUuids();
+ method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.os.ParcelUuid> getUuidsList();
method public boolean isBleScanAlwaysAvailable();
method public boolean isLeEnabled();
method @NonNull public static String nameForState(int);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean registerBluetoothConnectionCallback(@NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.BluetoothConnectionCallback);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean removeActiveDevice(int);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean removeOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void requestControllerActivityEnergyInfo(@NonNull android.os.ResultReceiver);
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void requestControllerActivityEnergyInfo(@NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnBluetoothActivityEnergyInfoListener);
method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BluetoothSocket retrieveConnectedRfcommSocket(@NonNull java.util.UUID);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean setActiveDevice(@NonNull android.bluetooth.BluetoothDevice, int);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int setDiscoverableTimeout(@NonNull java.time.Duration);
@@ -97,6 +97,10 @@ package android.bluetooth {
method public void onDeviceDisconnected(@NonNull android.bluetooth.BluetoothDevice, int);
}
+ public static interface BluetoothAdapter.OnBluetoothActivityEnergyInfoListener {
+ method public void onBluetoothActivityEnergyInfo(@Nullable android.bluetooth.BluetoothActivityEnergyInfo);
+ }
+
public static interface BluetoothAdapter.OnMetadataChangedListener {
method public void onMetadataChanged(@NonNull android.bluetooth.BluetoothDevice, int, @Nullable byte[]);
}
@@ -139,7 +143,7 @@ package android.bluetooth {
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int disconnect();
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean fetchUuidsWithSdp(int);
method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public String getAnonymizedAddress();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getBatteryLevel();
+ method @IntRange(from=0xffffff9c, to=100) @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getBatteryLevel();
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public String getIdentityAddress();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getMessageAccessPermission();
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public byte[] getMetadata(int);
@@ -339,12 +343,12 @@ package android.bluetooth {
public final class BluetoothLeAudio implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getAudioLocation(@NonNull android.bluetooth.BluetoothDevice);
- method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BluetoothLeAudioCodecStatus getCodecStatus(@NonNull android.bluetooth.BluetoothDevice);
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BluetoothLeAudioCodecStatus getCodecStatus(int);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothLeAudio.Callback);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void setCodecConfigPreference(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothLeAudioCodecConfig);
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void setCodecConfigPreference(int, @NonNull android.bluetooth.BluetoothLeAudioCodecConfig, @NonNull android.bluetooth.BluetoothLeAudioCodecConfig);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void setVolume(int);
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void setVolume(@IntRange(from=0, to=255) int);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void unregisterCallback(@NonNull android.bluetooth.BluetoothLeAudio.Callback);
field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED = "android.bluetooth.action.LE_AUDIO_ACTIVE_DEVICE_CHANGED";
field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_LE_AUDIO_GROUP_NODE_STATUS_CHANGED = "android.bluetooth.action.LE_AUDIO_GROUP_NODE_STATUS_CHANGED";
diff --git a/framework/java/android/bluetooth/BluetoothA2dp.java b/framework/java/android/bluetooth/BluetoothA2dp.java
index 8b27e7faef..6c15925d53 100644
--- a/framework/java/android/bluetooth/BluetoothA2dp.java
+++ b/framework/java/android/bluetooth/BluetoothA2dp.java
@@ -835,9 +835,14 @@ public final class BluetoothA2dp implements BluetoothProfile {
}
/**
- * Enables the optional codecs.
+ * Enables the optional codecs for the given device for this connection.
*
- * @param device the remote Bluetooth device.
+ * If the given device supports another codec type than
+ * {@link BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC}, this will switch to it.
+ * See {@link #setOptionalCodecsEnabled} to enable optional codecs by default
+ * when the given device is connected.
+ *
+ * @param device the remote Bluetooth device
* @hide
*/
@SystemApi
@@ -851,9 +856,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
}
/**
- * Disables the optional codecs.
+ * Disables the optional codecs for the given device.
*
- * @param device the remote Bluetooth device.
+ * When optional codecs are disabled, the device will use the default
+ * Bluetooth audio codec type.
+ * See {@link BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC}.
+ * See {@link #setOptionalCodecsEnabled} to disable optional codecs by default
+ * when the given device is connected.
+ *
+ * @param device the remote Bluetooth device
* @hide
*/
@SystemApi
@@ -870,7 +881,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* Enables or disables the optional codecs.
*
* @param device the remote Bluetooth device.
- * @param enable if true, enable the optional codecs, other disable them
+ * @param enable if true, enable the optional codecs, otherwise disable them
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
private void enableDisableOptionalCodecs(BluetoothDevice device, boolean enable) {
@@ -894,17 +905,18 @@ public final class BluetoothA2dp implements BluetoothProfile {
/**
* Returns whether this device supports optional codecs.
*
- * @param device The device to check
- * @return one of OPTIONAL_CODECS_SUPPORT_UNKNOWN, OPTIONAL_CODECS_NOT_SUPPORTED, or
- * OPTIONAL_CODECS_SUPPORTED.
+ * @param device the remote Bluetooth device
+ * @return whether the optional codecs are supported or not, or
+ * {@link #OPTIONAL_CODECS_SUPPORT_UNKNOWN} if the state
+ * can't be retrieved.
* @hide
*/
@SystemApi
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
- @OptionalCodecsSupportStatus
- public int isOptionalCodecsSupported(@NonNull BluetoothDevice device) {
+ public @OptionalCodecsSupportStatus int isOptionalCodecsSupported(
+ @NonNull BluetoothDevice device) {
if (DBG) log("isOptionalCodecsSupported(" + device + ")");
verifyDeviceNotNull(device, "isOptionalCodecsSupported");
final IBluetoothA2dp service = getService();
@@ -925,19 +937,20 @@ public final class BluetoothA2dp implements BluetoothProfile {
}
/**
- * Returns whether this device should have optional codecs enabled.
+ * Returns whether this device has its optional codecs enabled.
*
- * @param device The device in question.
- * @return one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
- * OPTIONAL_CODECS_PREF_DISABLED.
+ * @param device the remote Bluetooth device
+ * @return whether the optional codecs are enabled or not, or
+ * {@link #OPTIONAL_CODECS_PREF_UNKNOWN} if the state
+ * can't be retrieved.
* @hide
*/
@SystemApi
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
- @OptionalCodecsPreferenceStatus
- public int isOptionalCodecsEnabled(@NonNull BluetoothDevice device) {
+ public @OptionalCodecsPreferenceStatus int isOptionalCodecsEnabled(
+ @NonNull BluetoothDevice device) {
if (DBG) log("isOptionalCodecsEnabled(" + device + ")");
verifyDeviceNotNull(device, "isOptionalCodecsEnabled");
final IBluetoothA2dp service = getService();
@@ -958,12 +971,13 @@ public final class BluetoothA2dp implements BluetoothProfile {
}
/**
- * Sets a persistent preference for whether a given device should have optional codecs enabled.
+ * Sets the default state of optional codecs for the given device.
+ *
+ * Automatically enables or disables the optional codecs for the given device when
+ * connected.
*
- * @param device The device to set this preference for.
- * @param value Whether the optional codecs should be enabled for this device. This should be
- * one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
- * OPTIONAL_CODECS_PREF_DISABLED.
+ * @param device the remote Bluetooth device
+ * @param value whether the optional codecs should be enabled for this device
* @hide
*/
@SystemApi
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java
index de3f570d96..58ab06dffb 100644
--- a/framework/java/android/bluetooth/BluetoothAdapter.java
+++ b/framework/java/android/bluetooth/BluetoothAdapter.java
@@ -59,7 +59,6 @@ import android.os.IBinder;
import android.os.IpcDataCache;
import android.os.ParcelUuid;
import android.os.RemoteException;
-import android.os.ResultReceiver;
import android.sysprop.BluetoothProperties;
import android.util.Log;
import android.util.Pair;
@@ -832,6 +831,55 @@ public final class BluetoothAdapter {
};
/**
+ * Interface for Bluetooth activity energy info listener. Should be implemented by applications
+ * and set when calling {@link BluetoothAdapter#requestControllerActivityEnergyInfo}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface OnBluetoothActivityEnergyInfoListener {
+ /**
+ * Called when Bluetooth activity energy info is available.
+ * Note: this listener is triggered at most once for each call to
+ * {@link #requestControllerActivityEnergyInfo}.
+ *
+ * @param info the latest {@link BluetoothActivityEnergyInfo}, or null if unavailable.
+ */
+ void onBluetoothActivityEnergyInfo(@Nullable BluetoothActivityEnergyInfo info);
+ }
+
+ private static class OnBluetoothActivityEnergyInfoProxy
+ extends IBluetoothActivityEnergyInfoListener.Stub {
+ private final Object mLock = new Object();
+ @Nullable @GuardedBy("mLock") private Executor mExecutor;
+ @Nullable @GuardedBy("mLock") private OnBluetoothActivityEnergyInfoListener mListener;
+
+ OnBluetoothActivityEnergyInfoProxy(Executor executor,
+ OnBluetoothActivityEnergyInfoListener listener) {
+ mExecutor = executor;
+ mListener = listener;
+ }
+
+ @Override
+ public void onBluetoothActivityEnergyInfo(BluetoothActivityEnergyInfo info) {
+ Executor executor;
+ OnBluetoothActivityEnergyInfoListener listener;
+ synchronized (mLock) {
+ if (mExecutor == null || mListener == null) {
+ return;
+ }
+ executor = mExecutor;
+ listener = mListener;
+ // null out to allow garbage collection, prevent triggering listener more than once
+ mExecutor = null;
+ mListener = null;
+ }
+ Binder.clearCallingIdentity();
+ executor.execute(() -> listener.onBluetoothActivityEnergyInfo(info));
+ }
+ }
+
+ /**
* Get a handle to the default local Bluetooth adapter.
* <p>
* Currently Android only supports one Bluetooth adapter, but the API could
@@ -1488,11 +1536,10 @@ public final class BluetoothAdapter {
* @return the UUIDs supported by the local Bluetooth Adapter.
* @hide
*/
- @SystemApi
+ @UnsupportedAppUsage
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
- @SuppressLint(value = {"ArrayReturn", "NullableCollection"})
public @NonNull ParcelUuid[] getUuids() {
if (getState() != STATE_ON) {
return new ParcelUuid[0];
@@ -1516,6 +1563,18 @@ public final class BluetoothAdapter {
}
/**
+ * Get the UUIDs supported by the local Bluetooth adapter.
+ *
+ * @return a list of the UUIDs supported by the local Bluetooth Adapter.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public @NonNull List<ParcelUuid> getUuidsList() {
+ return Arrays.asList(getUuids());
+ }
+
+ /**
* Set the friendly Bluetooth name of the local Bluetooth adapter.
* <p>This name is visible to remote Bluetooth devices.
* <p>Valid Bluetooth names are a maximum of 248 bytes using UTF-8
@@ -2675,22 +2734,22 @@ public final class BluetoothAdapter {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
})
- public void requestControllerActivityEnergyInfo(@NonNull ResultReceiver result) {
- requireNonNull(result, "ResultReceiver cannot be null");
+ public void requestControllerActivityEnergyInfo(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OnBluetoothActivityEnergyInfoListener listener) {
+ requireNonNull(executor, "executor cannot be null");
+ requireNonNull(listener, "listener cannot be null");
try {
mServiceLock.readLock().lock();
if (mService != null) {
- mService.requestActivityInfo(result, mAttributionSource);
- result = null;
+ mService.requestActivityInfo(
+ new OnBluetoothActivityEnergyInfoProxy(executor, listener),
+ mAttributionSource);
}
} catch (RemoteException e) {
Log.e(TAG, "getControllerActivityEnergyInfoCallback: " + e);
} finally {
mServiceLock.readLock().unlock();
- if (result != null) {
- // Only send an immediate result if we failed.
- result.send(0, null);
- }
}
}
diff --git a/framework/java/android/bluetooth/BluetoothCodecConfig.java b/framework/java/android/bluetooth/BluetoothCodecConfig.java
index d0e426853c..16b787db8e 100644
--- a/framework/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/framework/java/android/bluetooth/BluetoothCodecConfig.java
@@ -536,6 +536,8 @@ public final class BluetoothCodecConfig implements Parcelable {
/**
* Returns the codec specific value1.
+ * As the value and usage differ for each codec, please refer to the concerned
+ * codec specification to obtain the codec specific information.
*/
public long getCodecSpecific1() {
return mCodecSpecific1;
@@ -543,6 +545,8 @@ public final class BluetoothCodecConfig implements Parcelable {
/**
* Returns the codec specific value2.
+ * As the value and usage differ for each codec, please refer to the concerned
+ * codec specification to obtain the codec specific information.
*/
public long getCodecSpecific2() {
return mCodecSpecific2;
@@ -550,6 +554,8 @@ public final class BluetoothCodecConfig implements Parcelable {
/**
* Returns the codec specific value3.
+ * As the value and usage differ for each codec, please refer to the concerned
+ * codec specification to obtain the codec specific information.
*/
public long getCodecSpecific3() {
return mCodecSpecific3;
@@ -557,6 +563,8 @@ public final class BluetoothCodecConfig implements Parcelable {
/**
* Returns the codec specific value4.
+ * As the value and usage differ for each codec, please refer to the concerned
+ * codec specification to obtain the codec specific information.
*/
public long getCodecSpecific4() {
return mCodecSpecific4;
diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java
index 978c8ed4ac..698e409723 100644
--- a/framework/java/android/bluetooth/BluetoothDevice.java
+++ b/framework/java/android/bluetooth/BluetoothDevice.java
@@ -19,6 +19,7 @@ package android.bluetooth;
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -794,6 +795,15 @@ public final class BluetoothDevice implements Parcelable, Attributable {
/**
* Broadcast Action: This intent is used to broadcast CONNECTION ACCESS REQUEST
*
+ * This action will trigger a prompt for the user to accept or deny giving the
+ * permission for this device. Permissions can be specified with
+ * {@link #EXTRA_ACCESS_REQUEST_TYPE}.
+ *
+ * The reply will be an {@link #ACTION_CONNECTION_ACCESS_REPLY} sent to the specified
+ * {@link #EXTRA_PACKAGE_NAME} and {@link #EXTRA_CLASS_NAME}.
+ *
+ * This action can be cancelled with {@link #ACTION_CONNECTION_ACCESS_CANCEL}.
+ *
* @hide
*/
@SystemApi
@@ -807,6 +817,13 @@ public final class BluetoothDevice implements Parcelable, Attributable {
/**
* Broadcast Action: This intent is used to broadcast CONNECTION ACCESS REPLY
*
+ * This action is the reply from {@link #ACTION_CONNECTION_ACCESS_REQUEST}
+ * that is sent to the specified {@link #EXTRA_PACKAGE_NAME}
+ * and {@link #EXTRA_CLASS_NAME}.
+ *
+ * See the extra fields {@link #EXTRA_CONNECTION_ACCESS_RESULT} and
+ * {@link #EXTRA_ALWAYS_ALLOWED} for possible results.
+ *
* @hide
*/
@SystemApi
@@ -844,7 +861,11 @@ public final class BluetoothDevice implements Parcelable, Attributable {
"android.bluetooth.device.action.SILENCE_MODE_CHANGED";
/**
- * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intent.
+ * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST}.
+ *
+ * Possible values are {@link #REQUEST_TYPE_PROFILE_CONNECTION},
+ * {@link #REQUEST_TYPE_PHONEBOOK_ACCESS}, {@link #REQUEST_TYPE_MESSAGE_ACCESS}
+ * and {@link #REQUEST_TYPE_SIM_ACCESS}
*
* @hide
*/
@@ -888,6 +909,8 @@ public final class BluetoothDevice implements Parcelable, Attributable {
/**
* Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intent.
*
+ * Possible values are {@link #CONNECTION_ACCESS_YES} and {@link #CONNECTION_ACCESS_NO}.
+ *
* @hide
*/
@SystemApi
@@ -1044,7 +1067,8 @@ public final class BluetoothDevice implements Parcelable, Attributable {
public static final int PAIRING_VARIANT_DISPLAY_PIN = 5;
/**
- * The user will be prompted to accept or deny the OOB pairing request
+ * The user will be prompted to accept or deny the OOB pairing request.
+ * This is used for Bluetooth 2.1 secure simple pairing.
*
* @hide
*/
@@ -1624,7 +1648,7 @@ public final class BluetoothDevice implements Parcelable, Attributable {
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
- public int getBatteryLevel() {
+ public @IntRange(from = -100, to = 100) int getBatteryLevel() {
if (DBG) log("getBatteryLevel()");
final IBluetooth service = sService;
final int defaultValue = BATTERY_LEVEL_BLUETOOTH_OFF;
@@ -2009,10 +2033,14 @@ public final class BluetoothDevice implements Parcelable, Attributable {
/**
* Disconnects all connected bluetooth profiles between the local and remote device.
- * Disconnection is asynchronous and you should listen to each profile's broadcast intent
+ * Disconnection is asynchronous, so you should listen to each profile's broadcast intent
* ACTION_CONNECTION_STATE_CHANGED to verify whether disconnection was successful. For example,
* to verify a2dp is disconnected, you would listen for
- * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}
+ * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}. Once all profiles have disconnected,
+ * the ACL link should come down and {@link #ACTION_ACL_DISCONNECTED} should be broadcast.
+ * <p>
+ * In the rare event that one or more profiles fail to disconnect, call this method again to
+ * send another request to disconnect each connected profile.
*
* @return whether the messages were successfully sent to try to disconnect all profiles
* @throws IllegalArgumentException if the device address is invalid
diff --git a/framework/java/android/bluetooth/BluetoothDevicePicker.java b/framework/java/android/bluetooth/BluetoothDevicePicker.java
index d17ab8d72a..d1fc0622e4 100644
--- a/framework/java/android/bluetooth/BluetoothDevicePicker.java
+++ b/framework/java/android/bluetooth/BluetoothDevicePicker.java
@@ -30,15 +30,37 @@ import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
*/
@SystemApi
public interface BluetoothDevicePicker {
+
+ /**
+ * Extra for filter type used with {@link #ACTION_LAUNCH}.
+ * The value must be a boolean indicating whether the device should need authentication or not.
+ */
@SuppressLint("ActionValue")
public static final String EXTRA_NEED_AUTH =
"android.bluetooth.devicepicker.extra.NEED_AUTH";
+
+ /**
+ * Extra for filter type used with {@link #ACTION_LAUNCH}.
+ * This extra must contain the filter type that will be applied to the device list.
+ * Possible values are {@link #FILTER_TYPE_ALL}, {@link #FILTER_TYPE_AUDIO},
+ * {@link #FILTER_TYPE_TRANSFER}, {@link #FILTER_TYPE_PANU}, and {@link #FILTER_TYPE_NAP}.
+ */
@SuppressLint("ActionValue")
public static final String EXTRA_FILTER_TYPE =
"android.bluetooth.devicepicker.extra.FILTER_TYPE";
+
+ /**
+ * Extra for filter type used with {@link #ACTION_LAUNCH}.
+ * This extra must contain the package name that called {@link #ACTION_LAUNCH}.
+ */
@SuppressLint("ActionValue")
public static final String EXTRA_LAUNCH_PACKAGE =
"android.bluetooth.devicepicker.extra.LAUNCH_PACKAGE";
+
+ /**
+ * Extra for filter type used with {@link #ACTION_LAUNCH}.
+ * This extra must contain the class name that called {@link #ACTION_LAUNCH}.
+ */
@SuppressLint("ActionValue")
public static final String EXTRA_LAUNCH_CLASS =
"android.bluetooth.devicepicker.extra.DEVICE_PICKER_LAUNCH_CLASS";
diff --git a/framework/java/android/bluetooth/BluetoothLeAudio.java b/framework/java/android/bluetooth/BluetoothLeAudio.java
index b81a8a43a0..91b7d499bb 100644
--- a/framework/java/android/bluetooth/BluetoothLeAudio.java
+++ b/framework/java/android/bluetooth/BluetoothLeAudio.java
@@ -22,6 +22,7 @@ import static android.bluetooth.BluetoothUtils.getSyncTimeout;
import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -152,7 +153,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
/**
* Intent used to broadcast group node status information.
*
- * <p>This intent will have 3 extra:
+ * <p>This intent will have 3 extras:
* <ul>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
* be null if no device is active. </li>
@@ -174,7 +175,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
/**
* Intent used to broadcast group status information.
*
- * <p>This intent will have 4 extra:
+ * <p>This intent will have 3 extras:
* <ul>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
* be null if no device is active. </li>
@@ -827,13 +828,13 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
}
/**
- * Get lead device for a group.
+ * Get Lead device for the group.
*
* Lead device is the device that can be used as an active device in the system.
* Active devices points to the Audio Device for the Le Audio group.
- * This method returns a list of Lead devices for all the connected LE Audio
- * groups and those devices should be used in the setActiveDevice() method by other parts
- * of the system, which wants to setActive a particular Le Audio Group.
+ * This method returns the Lead devices for the connected LE Audio
+ * group and this device should be used in the setActiveDevice() method by other parts
+ * of the system, which wants to set to active a particular Le Audio group.
*
* Note: getActiveDevice() returns the Lead device for the currently active LE Audio group.
* Note: When lead device gets disconnected, there will be new lead device for the group.
@@ -1161,7 +1162,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED
})
- public void setVolume(int volume) {
+ public void setVolume(@IntRange(from = 0, to = 255) int volume) {
if (VDBG) log("setVolume(vol: " + volume + " )");
final IBluetoothLeAudio service = getService();
if (service == null) {
@@ -1392,7 +1393,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
/**
* Gets the current codec status (configuration and capability).
*
- * @param device the remote Bluetooth device.
+ * @param groupId The group id
* @return the current codec status
* @hide
*/
@@ -1403,9 +1404,9 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED
})
- public BluetoothLeAudioCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
+ public BluetoothLeAudioCodecStatus getCodecStatus(int groupId) {
if (DBG) {
- Log.d(TAG, "getCodecStatus(" + device + ")");
+ Log.d(TAG, "getCodecStatus(" + groupId + ")");
}
final IBluetoothLeAudio service = getService();
@@ -1414,11 +1415,11 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
- } else if (mAdapter.isEnabled() && isValidDevice(device)) {
+ } else if (mAdapter.isEnabled()) {
try {
final SynchronousResultReceiver<BluetoothLeAudioCodecStatus> recv =
new SynchronousResultReceiver();
- service.getCodecStatus(device, mAttributionSource, recv);
+ service.getCodecStatus(groupId, mAttributionSource, recv);
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
} catch (TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
@@ -1433,9 +1434,11 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
/**
* Sets the codec configuration preference.
*
- * @param device the remote Bluetooth device.
- * @param codecConfig the codec configuration preference
+ * @param groupId the groupId
+ * @param inputCodecConfig the input codec configuration preference
+ * @param outputCodecConfig the output codec configuration preference
* @throws IllegalStateException if LE Audio Service is null
+ * @throws NullPointerException if any of the configs is null
* @hide
*/
@SystemApi
@@ -1444,14 +1447,13 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED
})
- public void setCodecConfigPreference(@NonNull BluetoothDevice device,
- @NonNull BluetoothLeAudioCodecConfig codecConfig) {
- if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")");
+ public void setCodecConfigPreference(int groupId,
+ @NonNull BluetoothLeAudioCodecConfig inputCodecConfig,
+ @NonNull BluetoothLeAudioCodecConfig outputCodecConfig) {
+ if (DBG) Log.d(TAG, "setCodecConfigPreference(" + groupId + ")");
- if (codecConfig == null) {
- Log.e(TAG, "setCodecConfigPreference: Codec config can't be null");
- throw new IllegalArgumentException("codecConfig cannot be null");
- }
+ Objects.requireNonNull(inputCodecConfig, " inputCodecConfig shall not be null");
+ Objects.requireNonNull(outputCodecConfig, " outputCodecConfig shall not be null");
final IBluetoothLeAudio service = getService();
@@ -1459,9 +1461,10 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
throw new IllegalStateException("Service is unavailable");
- } else if (mAdapter.isEnabled() && isValidDevice(device)) {
+ } else if (mAdapter.isEnabled()) {
try {
- service.setCodecConfigPreference(device, codecConfig, mAttributionSource);
+ service.setCodecConfigPreference(groupId, inputCodecConfig, outputCodecConfig,
+ mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
e.rethrowFromSystemServer();
diff --git a/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java b/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java
index 004bf6b84f..c91d13ffe0 100644
--- a/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java
+++ b/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java
@@ -72,7 +72,7 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000;
/** @hide */
- @IntDef(prefix = "SAMPLE_RATE_",
+ @IntDef(flag = true, prefix = "SAMPLE_RATE_",
value = {SAMPLE_RATE_NONE, SAMPLE_RATE_8000, SAMPLE_RATE_16000, SAMPLE_RATE_24000,
SAMPLE_RATE_32000, SAMPLE_RATE_44100, SAMPLE_RATE_48000})
@Retention(RetentionPolicy.SOURCE)
@@ -81,41 +81,45 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
/**
* Codec sample rate 0 Hz. Default value used for
* codec sample rate.
+ * Values are the bit mask as defined in the
+ * Bluetooth Assigned Numbers, Generic Audio,
+ * Supported_Sampling_Frequencies table
+ * Note: We use only part of it.
*/
public static final int SAMPLE_RATE_NONE = 0;
/**
* Codec sample rate 8000 Hz.
*/
- public static final int SAMPLE_RATE_8000 = 1;
+ public static final int SAMPLE_RATE_8000 = 0x01 << 0;
/**
* Codec sample rate 16000 Hz.
*/
- public static final int SAMPLE_RATE_16000 = 2;
+ public static final int SAMPLE_RATE_16000 = 0x01 << 2;
/**
* Codec sample rate 24000 Hz.
*/
- public static final int SAMPLE_RATE_24000 = 3;
+ public static final int SAMPLE_RATE_24000 = 0x01 << 4;
/**
* Codec sample rate 32000 Hz.
*/
- public static final int SAMPLE_RATE_32000 = 4;
+ public static final int SAMPLE_RATE_32000 = 0x01 << 5;
/**
* Codec sample rate 44100 Hz.
*/
- public static final int SAMPLE_RATE_44100 = 5;
+ public static final int SAMPLE_RATE_44100 = 0x01 << 6;
/**
* Codec sample rate 48000 Hz.
*/
- public static final int SAMPLE_RATE_48000 = 6;
+ public static final int SAMPLE_RATE_48000 = 0x01 << 7;
/** @hide */
- @IntDef(prefix = "BITS_PER_SAMPLE_",
+ @IntDef(flag = true, prefix = "BITS_PER_SAMPLE_",
value = {BITS_PER_SAMPLE_NONE, BITS_PER_SAMPLE_16, BITS_PER_SAMPLE_24,
BITS_PER_SAMPLE_32})
@Retention(RetentionPolicy.SOURCE)
@@ -130,42 +134,52 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
/**
* Codec bits per sample 16.
*/
- public static final int BITS_PER_SAMPLE_16 = 1;
+ public static final int BITS_PER_SAMPLE_16 = 0x01 << 0;
/**
* Codec bits per sample 24.
*/
- public static final int BITS_PER_SAMPLE_24 = 2;
+ public static final int BITS_PER_SAMPLE_24 = 0x01 << 1;
/**
* Codec bits per sample 32.
*/
- public static final int BITS_PER_SAMPLE_32 = 3;
+ public static final int BITS_PER_SAMPLE_32 = 0x01 << 3;
- /** @hide */
- @IntDef(prefix = "CHANNEL_MODE_",
- value = {CHANNEL_MODE_NONE, CHANNEL_MODE_MONO, CHANNEL_MODE_STEREO})
+ /**
+ * Values are the bit mask as defined in the
+ * Bluetooth Assigned Numbers, Generic Audio,
+ * Supported_Audio_Channel_Counts table
+ * Note: We use only part of it.
+ * @hide */
+ @IntDef(flag = true, prefix = "CHANNEL_COUNT_",
+ value = {CHANNEL_COUNT_NONE, CHANNEL_COUNT_1, CHANNEL_COUNT_2})
@Retention(RetentionPolicy.SOURCE)
- public @interface ChannelMode {}
+ public @interface ChannelCount {}
/**
* Codec channel mode NONE. Default value of the
* codec channel mode.
*/
- public static final int CHANNEL_MODE_NONE = 0;
+ public static final int CHANNEL_COUNT_NONE = 0;
/**
* Codec channel mode MONO.
*/
- public static final int CHANNEL_MODE_MONO = 1;
+ public static final int CHANNEL_COUNT_1 = 0x01 << 0;
/**
* Codec channel mode STEREO.
*/
- public static final int CHANNEL_MODE_STEREO = 2;
+ public static final int CHANNEL_COUNT_2 = 0x01 << 1;
- /** @hide */
- @IntDef(prefix = "FRAME_DURATION_",
+ /**
+ * Values are the bit mask as defined in the
+ * Bluetooth Assigned Numbers, Generic Audio,
+ * Supported_Frame_Durations table
+ *
+ * @hide */
+ @IntDef(flag = true, prefix = "FRAME_DURATION_",
value = {FRAME_DURATION_NONE, FRAME_DURATION_7500, FRAME_DURATION_10000})
@Retention(RetentionPolicy.SOURCE)
public @interface FrameDuration {}
@@ -178,20 +192,23 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
/**
* Frame duration 7500 us.
*/
- public static final int FRAME_DURATION_7500 = 1;
+ public static final int FRAME_DURATION_7500 = 0x01 << 0;
/**
* Frame duration 10000 us.
*/
- public static final int FRAME_DURATION_10000 = 2;
+ public static final int FRAME_DURATION_10000 = 0x01 << 1;
private final @SourceCodecType int mCodecType;
private final @CodecPriority int mCodecPriority;
private final @SampleRate int mSampleRate;
private final @BitsPerSample int mBitsPerSample;
- private final @ChannelMode int mChannelMode;
+ private final @ChannelCount int mChannelCount;
private final @FrameDuration int mFrameDuration;
private final int mOctetsPerFrame;
+ private final int mMinOctetsPerFrame;
+ private final int mMaxOctetsPerFrame;
+
/**
* Creates a new BluetoothLeAudioCodecConfig.
@@ -200,21 +217,26 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
* @param codecPriority the priority of this codec
* @param sampleRate the codec sample rate
* @param bitsPerSample the bits per sample of this codec
- * @param channelMode the channel mode of this codec
+ * @param channelCount the channel count of this codec
* @param frameDuration the frame duration of this codec
* @param octetsPerFrame the octets per frame of this codec
+ * @param minOctetsPerFrame the minimum octets per frame of this codec
+ * @param maxOctetsPerFrame the maximum octets per frame of this codec
*/
private BluetoothLeAudioCodecConfig(@SourceCodecType int codecType,
@CodecPriority int codecPriority, @SampleRate int sampleRate,
- @BitsPerSample int bitsPerSample, @ChannelMode int channelMode,
- @FrameDuration int frameDuration, int octetsPerFrame) {
+ @BitsPerSample int bitsPerSample, @ChannelCount int channelCount,
+ @FrameDuration int frameDuration, int octetsPerFrame,
+ int minOctetsPerFrame, int maxOctetsPerFrame) {
mCodecType = codecType;
mCodecPriority = codecPriority;
mSampleRate = sampleRate;
mBitsPerSample = bitsPerSample;
- mChannelMode = channelMode;
+ mChannelCount = channelCount;
mFrameDuration = frameDuration;
mOctetsPerFrame = octetsPerFrame;
+ mMinOctetsPerFrame = minOctetsPerFrame;
+ mMaxOctetsPerFrame = maxOctetsPerFrame;
}
@Override
@@ -233,11 +255,14 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
int codecPriority = in.readInt();
int sampleRate = in.readInt();
int bitsPerSample = in.readInt();
- int channelMode = in.readInt();
+ int channelCount = in.readInt();
int frameDuration = in.readInt();
int octetsPerFrame = in.readInt();
+ int minOctetsPerFrame = in.readInt();
+ int maxOctetsPerFrame = in.readInt();
return new BluetoothLeAudioCodecConfig(codecType, codecPriority, sampleRate,
- bitsPerSample, channelMode, frameDuration, octetsPerFrame);
+ bitsPerSample, channelCount, frameDuration, octetsPerFrame,
+ minOctetsPerFrame, maxOctetsPerFrame);
}
public BluetoothLeAudioCodecConfig[] newArray(int size) {
@@ -251,17 +276,21 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
out.writeInt(mCodecPriority);
out.writeInt(mSampleRate);
out.writeInt(mBitsPerSample);
- out.writeInt(mChannelMode);
+ out.writeInt(mChannelCount);
out.writeInt(mFrameDuration);
out.writeInt(mOctetsPerFrame);
+ out.writeInt(mMinOctetsPerFrame);
+ out.writeInt(mMaxOctetsPerFrame);
}
@Override
public String toString() {
return "{codecName:" + getCodecName() + ",mCodecType:" + mCodecType
+ ",mCodecPriority:" + mCodecPriority + ",mSampleRate:" + mSampleRate
- + ",mBitsPerSample:" + mBitsPerSample + ",mChannelMode:" + mChannelMode
- + ",mFrameDuration:" + mFrameDuration + ",mOctetsPerFrame:" + mOctetsPerFrame + "}";
+ + ",mBitsPerSample:" + mBitsPerSample + ",mChannelCount:" + mChannelCount
+ + ",mFrameDuration:" + mFrameDuration + ",mOctetsPerFrame:" + mOctetsPerFrame
+ + ",mMinOctetsPerFrame:" + mMinOctetsPerFrame
+ + ",mMaxOctetsPerFrame:" + mMaxOctetsPerFrame + "}";
}
/**
@@ -316,8 +345,8 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
/**
* Returns the codec channel mode.
*/
- public @ChannelMode int getChannelMode() {
- return mChannelMode;
+ public @ChannelCount int getChannelCount() {
+ return mChannelCount;
}
/**
@@ -334,6 +363,20 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
return mOctetsPerFrame;
}
+ /**
+ * Returns the minimum octets per frame
+ */
+ public int getMinOctetsPerFrame() {
+ return mMinOctetsPerFrame;
+ }
+
+ /**
+ * Returns the maximum octets per frame
+ */
+ public int getMaxOctetsPerFrame() {
+ return mMaxOctetsPerFrame;
+ }
+
@Override
public boolean equals(@NonNull Object o) {
if (o instanceof BluetoothLeAudioCodecConfig) {
@@ -342,9 +385,11 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
&& other.getCodecPriority() == mCodecPriority
&& other.getSampleRate() == mSampleRate
&& other.getBitsPerSample() == mBitsPerSample
- && other.getChannelMode() == mChannelMode
+ && other.getChannelCount() == mChannelCount
&& other.getFrameDuration() == mFrameDuration
- && other.getOctetsPerFrame() == mOctetsPerFrame);
+ && other.getOctetsPerFrame() == mOctetsPerFrame
+ && other.getMinOctetsPerFrame() == mMinOctetsPerFrame
+ && other.getMaxOctetsPerFrame() == mMaxOctetsPerFrame);
}
return false;
}
@@ -356,7 +401,8 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(mCodecType, mCodecPriority, mSampleRate,
- mBitsPerSample, mChannelMode, mFrameDuration, mOctetsPerFrame);
+ mBitsPerSample, mChannelCount, mFrameDuration, mOctetsPerFrame,
+ mMinOctetsPerFrame, mMaxOctetsPerFrame);
}
/**
@@ -369,9 +415,11 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
private int mCodecPriority = BluetoothLeAudioCodecConfig.CODEC_PRIORITY_DEFAULT;
private int mSampleRate = BluetoothLeAudioCodecConfig.SAMPLE_RATE_NONE;
private int mBitsPerSample = BluetoothLeAudioCodecConfig.BITS_PER_SAMPLE_NONE;
- private int mChannelMode = BluetoothLeAudioCodecConfig.CHANNEL_MODE_NONE;
+ private int mChannelCount = BluetoothLeAudioCodecConfig.CHANNEL_COUNT_NONE;
private int mFrameDuration = BluetoothLeAudioCodecConfig.FRAME_DURATION_NONE;
private int mOctetsPerFrame = 0;
+ private int mMinOctetsPerFrame = 0;
+ private int mMaxOctetsPerFrame = 0;
public Builder() {}
@@ -380,9 +428,11 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
mCodecPriority = config.getCodecPriority();
mSampleRate = config.getSampleRate();
mBitsPerSample = config.getBitsPerSample();
- mChannelMode = config.getChannelMode();
+ mChannelCount = config.getChannelCount();
mFrameDuration = config.getFrameDuration();
mOctetsPerFrame = config.getOctetsPerFrame();
+ mMinOctetsPerFrame = config.getMinOctetsPerFrame();
+ mMaxOctetsPerFrame = config.getMaxOctetsPerFrame();
}
/**
@@ -430,13 +480,13 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
}
/**
- * Set the channel mode for Bluetooth LE audio codec config.
+ * Set the channel count for Bluetooth LE audio codec config.
*
- * @param channelMode of this codec
+ * @param channelCount of this codec
* @return the same Builder instance
*/
- public @NonNull Builder setChannelMode(@ChannelMode int channelMode) {
- mChannelMode = channelMode;
+ public @NonNull Builder setChannelCount(@ChannelCount int channelCount) {
+ mChannelCount = channelCount;
return this;
}
@@ -463,12 +513,35 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
}
/**
+ * Set the minimum octets per frame for Bluetooth LE audio codec config.
+ *
+ * @param minOctetsPerFrame of this codec
+ * @return the same Builder instance
+ */
+ public @NonNull Builder setMinOctetsPerFrame(int minOctetsPerFrame) {
+ mMinOctetsPerFrame = minOctetsPerFrame;
+ return this;
+ }
+
+ /**
+ * Set the maximum octets per frame for Bluetooth LE audio codec config.
+ *
+ * @param maxOctetsPerFrame of this codec
+ * @return the same Builder instance
+ */
+ public @NonNull Builder setMaxOctetsPerFrame(int maxOctetsPerFrame) {
+ mMaxOctetsPerFrame = maxOctetsPerFrame;
+ return this;
+ }
+
+ /**
* Build {@link BluetoothLeAudioCodecConfig}.
* @return new BluetoothLeAudioCodecConfig built
*/
public @NonNull BluetoothLeAudioCodecConfig build() {
return new BluetoothLeAudioCodecConfig(mCodecType, mCodecPriority, mSampleRate,
- mBitsPerSample, mChannelMode, mFrameDuration, mOctetsPerFrame);
+ mBitsPerSample, mChannelCount, mFrameDuration, mOctetsPerFrame,
+ mMinOctetsPerFrame, mMaxOctetsPerFrame);
}
}
}
diff --git a/framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java b/framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java
index 399ffa743c..bdb9d5d5c6 100644
--- a/framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java
+++ b/framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java
@@ -41,29 +41,47 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
public static final String EXTRA_LE_AUDIO_CODEC_STATUS =
"android.bluetooth.extra.LE_AUDIO_CODEC_STATUS";
- private final @Nullable BluetoothLeAudioCodecConfig mCodecConfig;
- private final @Nullable List<BluetoothLeAudioCodecConfig> mCodecsLocalCapabilities;
- private final @Nullable List<BluetoothLeAudioCodecConfig> mCodecsSelectableCapabilities;
+ private final @Nullable BluetoothLeAudioCodecConfig mInputCodecConfig;
+ private final @Nullable BluetoothLeAudioCodecConfig mOutputCodecConfig;
+ private final @Nullable List<BluetoothLeAudioCodecConfig> mInputCodecsLocalCapabilities;
+ private final @Nullable List<BluetoothLeAudioCodecConfig> mOutputCodecsLocalCapabilities;
+ private final @Nullable List<BluetoothLeAudioCodecConfig> mInputCodecsSelectableCapabilities;
+ private final @Nullable List<BluetoothLeAudioCodecConfig> mOutputCodecsSelectableCapabilities;
/**
* Represents the codec status for a Bluetooth LE Audio source device.
*
- * @param codecConfig the current code configutration.
- * @param codecsLocalCapabilities the local codecs capabilities.
- * @param codecsSelectableCapabilities the selectable codecs capabilities.
+ * @param inputCodecConfig the current input code configutration.
+ * @param outputCodecConfig the current output code configutration.
+ * @param inputCodecsLocalCapabilities the local input codecs capabilities.
+ * @param outputCodecsLocalCapabilities the local output codecs capabilities.
+ * @param inputCodecsSelectableCapabilities the selectable input codecs capabilities.
+ * @param outputCodecsSelectableCapabilities the selectable output codecs capabilities.
*/
- public BluetoothLeAudioCodecStatus(@Nullable BluetoothLeAudioCodecConfig codecConfig,
- @NonNull List<BluetoothLeAudioCodecConfig> codecsLocalCapabilities,
- @NonNull List<BluetoothLeAudioCodecConfig> codecsSelectableCapabilities) {
- mCodecConfig = codecConfig;
- mCodecsLocalCapabilities = codecsLocalCapabilities;
- mCodecsSelectableCapabilities = codecsSelectableCapabilities;
+ public BluetoothLeAudioCodecStatus(@Nullable BluetoothLeAudioCodecConfig inputCodecConfig,
+ @Nullable BluetoothLeAudioCodecConfig outputCodecConfig,
+ @NonNull List<BluetoothLeAudioCodecConfig> inputCodecsLocalCapabilities,
+ @NonNull List<BluetoothLeAudioCodecConfig> outputCodecsLocalCapabilities,
+ @NonNull List<BluetoothLeAudioCodecConfig> inputCodecsSelectableCapabilities,
+ @NonNull List<BluetoothLeAudioCodecConfig> outputCodecsSelectableCapabilities) {
+ mInputCodecConfig = inputCodecConfig;
+ mOutputCodecConfig = outputCodecConfig;
+ mInputCodecsLocalCapabilities = inputCodecsLocalCapabilities;
+ mOutputCodecsLocalCapabilities = outputCodecsLocalCapabilities;
+ mInputCodecsSelectableCapabilities = inputCodecsSelectableCapabilities;
+ mOutputCodecsSelectableCapabilities = outputCodecsSelectableCapabilities;
}
private BluetoothLeAudioCodecStatus(Parcel in) {
- mCodecConfig = in.readTypedObject(BluetoothLeAudioCodecConfig.CREATOR);
- mCodecsLocalCapabilities = in.createTypedArrayList(BluetoothLeAudioCodecConfig.CREATOR);
- mCodecsSelectableCapabilities =
+ mInputCodecConfig = in.readTypedObject(BluetoothLeAudioCodecConfig.CREATOR);
+ mOutputCodecConfig = in.readTypedObject(BluetoothLeAudioCodecConfig.CREATOR);
+ mInputCodecsLocalCapabilities =
+ in.createTypedArrayList(BluetoothLeAudioCodecConfig.CREATOR);
+ mOutputCodecsLocalCapabilities =
+ in.createTypedArrayList(BluetoothLeAudioCodecConfig.CREATOR);
+ mInputCodecsSelectableCapabilities =
+ in.createTypedArrayList(BluetoothLeAudioCodecConfig.CREATOR);
+ mOutputCodecsSelectableCapabilities =
in.createTypedArrayList(BluetoothLeAudioCodecConfig.CREATOR);
}
@@ -71,10 +89,16 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
public boolean equals(@Nullable Object o) {
if (o instanceof BluetoothLeAudioCodecStatus) {
BluetoothLeAudioCodecStatus other = (BluetoothLeAudioCodecStatus) o;
- return (Objects.equals(other.mCodecConfig, mCodecConfig)
- && sameCapabilities(other.mCodecsLocalCapabilities, mCodecsLocalCapabilities)
- && sameCapabilities(other.mCodecsSelectableCapabilities,
- mCodecsSelectableCapabilities));
+ return (Objects.equals(other.mInputCodecConfig, mInputCodecConfig)
+ && Objects.equals(other.mOutputCodecConfig, mOutputCodecConfig)
+ && sameCapabilities(other.mInputCodecsLocalCapabilities,
+ mInputCodecsLocalCapabilities)
+ && sameCapabilities(other.mOutputCodecsLocalCapabilities,
+ mOutputCodecsLocalCapabilities)
+ && sameCapabilities(other.mInputCodecsSelectableCapabilities,
+ mInputCodecsSelectableCapabilities)
+ && sameCapabilities(other.mOutputCodecsSelectableCapabilities,
+ mOutputCodecsSelectableCapabilities));
}
return false;
}
@@ -101,19 +125,67 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
return c1.containsAll(c2);
}
+ private boolean isCodecConfigSelectable(BluetoothLeAudioCodecConfig codecConfig,
+ BluetoothLeAudioCodecConfig selectableConfig) {
+ if (codecConfig.getCodecType() != selectableConfig.getCodecType()) {
+ return false;
+ }
+ if ((codecConfig.getFrameDuration() != BluetoothLeAudioCodecConfig.FRAME_DURATION_NONE)
+ && ((codecConfig.getFrameDuration() & selectableConfig.getFrameDuration()) == 0)) {
+ return false;
+ }
+ if ((codecConfig.getChannelCount() != BluetoothLeAudioCodecConfig.CHANNEL_COUNT_NONE)
+ && ((codecConfig.getChannelCount() & selectableConfig.getChannelCount()) == 0)) {
+ return false;
+ }
+ if ((codecConfig.getSampleRate() != BluetoothLeAudioCodecConfig.SAMPLE_RATE_NONE)
+ && ((codecConfig.getSampleRate() & selectableConfig.getSampleRate()) == 0)) {
+ return false;
+ }
+ if ((codecConfig.getBitsPerSample() != BluetoothLeAudioCodecConfig.BITS_PER_SAMPLE_NONE)
+ && ((codecConfig.getBitsPerSample() & selectableConfig.getBitsPerSample()) == 0)) {
+ return false;
+ }
+ if ((codecConfig.getOctetsPerFrame() != 0)
+ && ((codecConfig.getOctetsPerFrame() < selectableConfig.getMinOctetsPerFrame())
+ || (codecConfig.getOctetsPerFrame() > selectableConfig.getMaxOctetsPerFrame()))) {
+ return false;
+ }
+ return true;
+ }
/**
- * Checks whether the codec config matches the selectable capabilities.
+ * Checks whether the Input codec config matches the selectable capabilities.
* Any parameters of the codec config with NONE value will be considered a wildcard matching.
*
* @param codecConfig the codec config to compare against
* @return {@code true} if the codec config matches, {@code false} otherwise
*/
- public boolean isCodecConfigSelectable(@Nullable BluetoothLeAudioCodecConfig codecConfig) {
+ public boolean isInputCodecConfigSelectable(@Nullable BluetoothLeAudioCodecConfig codecConfig) {
if (codecConfig == null) {
return false;
}
- for (BluetoothLeAudioCodecConfig selectableConfig : mCodecsSelectableCapabilities) {
- if (codecConfig.equals(selectableConfig)) {
+ for (BluetoothLeAudioCodecConfig selectableConfig : mInputCodecsSelectableCapabilities) {
+ if (isCodecConfigSelectable(codecConfig, selectableConfig)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks whether the Output codec config matches the selectable capabilities.
+ * Any parameters of the codec config with NONE value will be considered a wildcard matching.
+ *
+ * @param codecConfig the codec config to compare against
+ * @return {@code true} if the codec config matches, {@code false} otherwise
+ */
+ public boolean isOutputCodecConfigSelectable(
+ @Nullable BluetoothLeAudioCodecConfig codecConfig) {
+ if (codecConfig == null) {
+ return false;
+ }
+ for (BluetoothLeAudioCodecConfig selectableConfig : mOutputCodecsSelectableCapabilities) {
+ if (isCodecConfigSelectable(codecConfig, selectableConfig)) {
return true;
}
}
@@ -125,7 +197,9 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
*/
@Override
public int hashCode() {
- return Objects.hash(mCodecConfig, mCodecsLocalCapabilities, mCodecsLocalCapabilities);
+ return Objects.hash(mInputCodecConfig, mOutputCodecConfig,
+ mInputCodecsLocalCapabilities, mOutputCodecsLocalCapabilities,
+ mInputCodecsSelectableCapabilities, mOutputCodecsSelectableCapabilities);
}
/**
@@ -134,9 +208,12 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
*/
@Override
public String toString() {
- return "{mCodecConfig:" + mCodecConfig
- + ",mCodecsLocalCapabilities:" + mCodecsLocalCapabilities
- + ",mCodecsSelectableCapabilities:" + mCodecsSelectableCapabilities
+ return "{mInputCodecConfig:" + mInputCodecConfig
+ + ",mOutputCodecConfig:" + mOutputCodecConfig
+ + ",mInputCodecsLocalCapabilities:" + mInputCodecsLocalCapabilities
+ + ",mOutputCodecsLocalCapabilities:" + mOutputCodecsLocalCapabilities
+ + ",mInputCodecsSelectableCapabilities:" + mInputCodecsSelectableCapabilities
+ + ",mOutputCodecsSelectableCapabilities:" + mOutputCodecsSelectableCapabilities
+ "}";
}
@@ -171,38 +248,71 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
*/
@Override
public void writeToParcel(@NonNull Parcel out, int flags) {
- out.writeTypedObject(mCodecConfig, flags);
- out.writeTypedList(mCodecsLocalCapabilities);
- out.writeTypedList(mCodecsSelectableCapabilities);
+ out.writeTypedObject(mInputCodecConfig, flags);
+ out.writeTypedObject(mOutputCodecConfig, flags);
+ out.writeTypedList(mInputCodecsLocalCapabilities);
+ out.writeTypedList(mOutputCodecsLocalCapabilities);
+ out.writeTypedList(mInputCodecsSelectableCapabilities);
+ out.writeTypedList(mOutputCodecsSelectableCapabilities);
+ }
+
+ /**
+ * Returns the current Input codec configuration.
+ *
+ * @return The current input codec config.
+ */
+ public @Nullable BluetoothLeAudioCodecConfig getInputCodecConfig() {
+ return mInputCodecConfig;
}
/**
- * Returns the current codec configuration.
+ * Returns the current Output codec configuration.
*
- * @return The current codec config.
+ * @return The current output codec config.
*/
- public @Nullable BluetoothLeAudioCodecConfig getCodecConfig() {
- return mCodecConfig;
+ public @Nullable BluetoothLeAudioCodecConfig getOutputCodecConfig() {
+ return mOutputCodecConfig;
}
/**
- * Returns the codecs local capabilities.
+ * Returns the input codecs local capabilities.
*
* @return The list of codec config that supported by the local system.
*/
- public @NonNull List<BluetoothLeAudioCodecConfig> getCodecLocalCapabilities() {
- return (mCodecsLocalCapabilities == null)
- ? Collections.emptyList() : mCodecsLocalCapabilities;
+ public @NonNull List<BluetoothLeAudioCodecConfig> getInputCodecLocalCapabilities() {
+ return (mInputCodecsLocalCapabilities == null)
+ ? Collections.emptyList() : mInputCodecsLocalCapabilities;
+ }
+
+ /**
+ * Returns the output codecs local capabilities.
+ *
+ * @return The list of codec config that supported by the local system.
+ */
+ public @NonNull List<BluetoothLeAudioCodecConfig> getOutputCodecLocalCapabilities() {
+ return (mOutputCodecsLocalCapabilities == null)
+ ? Collections.emptyList() : mOutputCodecsLocalCapabilities;
+ }
+
+ /**
+ * Returns the Input codecs selectable capabilities.
+ *
+ * @return The list of codec config that supported by both of the local system and
+ * remote devices.
+ */
+ public @NonNull List<BluetoothLeAudioCodecConfig> getInputCodecSelectableCapabilities() {
+ return (mInputCodecsSelectableCapabilities == null)
+ ? Collections.emptyList() : mInputCodecsSelectableCapabilities;
}
/**
- * Returns the codecs selectable capabilities.
+ * Returns the Output codecs selectable capabilities.
*
* @return The list of codec config that supported by both of the local system and
* remote devices.
*/
- public @NonNull List<BluetoothLeAudioCodecConfig> getCodecSelectableCapabilities() {
- return (mCodecsSelectableCapabilities == null)
- ? Collections.emptyList() : mCodecsSelectableCapabilities;
+ public @NonNull List<BluetoothLeAudioCodecConfig> getOutputCodecSelectableCapabilities() {
+ return (mOutputCodecsSelectableCapabilities == null)
+ ? Collections.emptyList() : mOutputCodecsSelectableCapabilities;
}
}
diff --git a/system/binder/Android.bp b/system/binder/Android.bp
index c5b0a61e99..475f91d25c 100644
--- a/system/binder/Android.bp
+++ b/system/binder/Android.bp
@@ -20,6 +20,7 @@ filegroup {
"android/bluetooth/IBluetooth.aidl",
"android/bluetooth/IBluetoothA2dp.aidl",
"android/bluetooth/IBluetoothA2dpSink.aidl",
+ "android/bluetooth/IBluetoothActivityEnergyInfoListener.aidl",
"android/bluetooth/IBluetoothAvrcpController.aidl",
"android/bluetooth/IBluetoothAvrcpTarget.aidl",
"android/bluetooth/IBluetoothBattery.aidl",
diff --git a/system/binder/android/bluetooth/IBluetooth.aidl b/system/binder/android/bluetooth/IBluetooth.aidl
index 369f7e5410..2404e81031 100644
--- a/system/binder/android/bluetooth/IBluetooth.aidl
+++ b/system/binder/android/bluetooth/IBluetooth.aidl
@@ -17,6 +17,7 @@
package android.bluetooth;
import android.app.PendingIntent;
+import android.bluetooth.IBluetoothActivityEnergyInfoListener;
import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothConnectionCallback;
import android.bluetooth.IBluetoothMetadataListener;
@@ -231,7 +232,7 @@ interface IBluetooth
* The result code is ignored.
*/
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
- oneway void requestActivityInfo(in ResultReceiver result, in AttributionSource attributionSource);
+ oneway void requestActivityInfo(in IBluetoothActivityEnergyInfoListener listener, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
oneway void onLeServiceUp(in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
diff --git a/system/binder/android/bluetooth/IBluetoothActivityEnergyInfoListener.aidl b/system/binder/android/bluetooth/IBluetoothActivityEnergyInfoListener.aidl
new file mode 100644
index 0000000000..24ae14adb9
--- /dev/null
+++ b/system/binder/android/bluetooth/IBluetoothActivityEnergyInfoListener.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.bluetooth.BluetoothActivityEnergyInfo;
+
+/**
+ * Interface for Bluetooth activity energy info listener.
+ *
+ * {@hide}
+ */
+oneway interface IBluetoothActivityEnergyInfoListener
+{
+ /**
+ * AdapterService to BluetoothAdapter callback providing current Bluetooth
+ * activity energy info.
+ * @param info the Bluetooth activity energy info
+ */
+ void onBluetoothActivityEnergyInfo(in BluetoothActivityEnergyInfo info);
+} \ No newline at end of file
diff --git a/system/binder/android/bluetooth/IBluetoothLeAudio.aidl b/system/binder/android/bluetooth/IBluetoothLeAudio.aidl
index 7039c744ae..7a3a05a739 100644
--- a/system/binder/android/bluetooth/IBluetoothLeAudio.aidl
+++ b/system/binder/android/bluetooth/IBluetoothLeAudio.aidl
@@ -54,9 +54,9 @@ oneway interface IBluetoothLeAudio {
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void getConnectedGroupLeadDevice(int groupId, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void getCodecStatus(in BluetoothDevice device, in AttributionSource source, in SynchronousResultReceiver receiver);
+ void getCodecStatus(in int groupId, in AttributionSource source, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void setCodecConfigPreference(in BluetoothDevice device, in BluetoothLeAudioCodecConfig codecConfig, in AttributionSource source);
+ void setCodecConfigPreference(in int groupId, in BluetoothLeAudioCodecConfig inputCodecConfig, in BluetoothLeAudioCodecConfig outputCodecConfig, in AttributionSource source);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
void registerCallback(in IBluetoothLeAudioCallback callback, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc
index 1ab4ca5592..bf385f8617 100644
--- a/system/bta/dm/bta_dm_act.cc
+++ b/system/bta/dm/bta_dm_act.cc
@@ -3100,7 +3100,7 @@ static void bta_dm_set_eir(char* local_name) {
if (free_eir_length)
UINT8_TO_STREAM(p, 0); /* terminator of significant part */
- BTM_WriteEIR(p_buf);
+ get_btm_client_interface().eir.BTM_WriteEIR(p_buf);
}
#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h
index 3c0bd4b38a..b3049c80ac 100644
--- a/system/bta/include/bta_api.h
+++ b/system/bta/include/bta_api.h
@@ -775,7 +775,7 @@ tBTA_STATUS BTA_DmGetCachedRemoteName(const RawAddress& remote_device,
*
******************************************************************************/
extern void BTA_DmBond(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type,
- tBT_TRANSPORT transport, tBLE_ADDR_TYPE device_type);
+ tBT_TRANSPORT transport, tBT_DEVICE_TYPE device_type);
/*******************************************************************************
*
diff --git a/system/bta/le_audio/state_machine_test.cc b/system/bta/le_audio/state_machine_test.cc
index c063873af9..5fa4e5a94b 100644
--- a/system/bta/le_audio/state_machine_test.cc
+++ b/system/bta/le_audio/state_machine_test.cc
@@ -173,7 +173,7 @@ class StateMachineTest : public Test {
: ((uint16_t)(remote_bda.address[0] ^
remote_bda.address[1] ^
remote_bda.address[2]))
- << 8 ||
+ << 8 |
(remote_bda.address[3] ^ remote_bda.address[4] ^
remote_bda.address[5]);
}));
diff --git a/system/main/Android.bp b/system/main/Android.bp
index b8aa2955ef..8a147b3177 100644
--- a/system/main/Android.bp
+++ b/system/main/Android.bp
@@ -101,7 +101,7 @@ cc_library {
"-DBUILDCFG",
],
sanitize: {
- never: true,
+ scs: true,
},
host_supported: true,
min_sdk_version: "30",
diff --git a/system/main/shim/btm_api.cc b/system/main/shim/btm_api.cc
index d5f3023c4e..646a67cab0 100644
--- a/system/main/shim/btm_api.cc
+++ b/system/main/shim/btm_api.cc
@@ -878,13 +878,6 @@ tBTM_STATUS bluetooth::shim::BTM_ClearInqDb(const RawAddress* p_bda) {
return BTM_NO_RESOURCES;
}
-tBTM_STATUS bluetooth::shim::BTM_WriteEIR(BT_HDR* p_buff) {
- LOG_INFO("UNIMPLEMENTED %s", __func__);
- CHECK(p_buff != nullptr);
- osi_free(p_buff);
- return BTM_NO_RESOURCES;
-}
-
bool bluetooth::shim::BTM_HasEirService(const uint32_t* p_eir_uuid,
uint16_t uuid16) {
LOG_INFO("UNIMPLEMENTED %s", __func__);
diff --git a/system/main/shim/btm_api.h b/system/main/shim/btm_api.h
index 65bcc60a8e..93f261ee5c 100644
--- a/system/main/shim/btm_api.h
+++ b/system/main/shim/btm_api.h
@@ -289,21 +289,6 @@ tBTM_STATUS BTM_ClearInqDb(const RawAddress* p_bda);
/*******************************************************************************
*
- * Function BTM_WriteEIR
- *
- * Description This function is called to write EIR data to controller.
- *
- * Parameters p_buff - allocated HCI command buffer including extended
- * inquriry response
- *
- * Returns BTM_SUCCESS - if successful
- * BTM_MODE_UNSUPPORTED - if local device cannot support it
- *
- ******************************************************************************/
-tBTM_STATUS BTM_WriteEIR(BT_HDR* p_buff);
-
-/*******************************************************************************
- *
* Function BTM_HasEirService
*
* Description This function is called to know if UUID in bit map of UUID.
diff --git a/system/main/shim/le_advertising_manager.cc b/system/main/shim/le_advertising_manager.cc
index 1267752120..42313689af 100644
--- a/system/main/shim/le_advertising_manager.cc
+++ b/system/main/shim/le_advertising_manager.cc
@@ -374,5 +374,7 @@ BleAdvertiserInterface* bluetooth::shim::get_ble_advertiser_instance() {
};
void bluetooth::shim::init_advertising_manager() {
- bt_le_advertiser_instance->Init();
+ static_cast<BleAdvertiserInterfaceImpl*>(
+ bluetooth::shim::get_ble_advertiser_instance())
+ ->Init();
}
diff --git a/system/test/mock/mock_main_shim_btm_api.cc b/system/test/mock/mock_main_shim_btm_api.cc
index a2a13194c4..975374d009 100644
--- a/system/test/mock/mock_main_shim_btm_api.cc
+++ b/system/test/mock/mock_main_shim_btm_api.cc
@@ -217,10 +217,6 @@ tBTM_STATUS bluetooth::shim::BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb,
mock_function_count_map[__func__]++;
return BTM_SUCCESS;
}
-tBTM_STATUS bluetooth::shim::BTM_WriteEIR(BT_HDR* p_buff) {
- mock_function_count_map[__func__]++;
- return BTM_SUCCESS;
-}
tBTM_STATUS bluetooth::shim::btm_sec_mx_access_request(
const RawAddress& bd_addr, bool is_originator,
uint16_t security_requirement, tBTM_SEC_CALLBACK* p_callback,
diff --git a/system/test/mock/mock_stack_btm.cc b/system/test/mock/mock_stack_btm.cc
index 89ef550e5d..d72c821d3d 100644
--- a/system/test/mock/mock_stack_btm.cc
+++ b/system/test/mock/mock_stack_btm.cc
@@ -30,10 +30,13 @@ void BTM_BleBackgroundObserve(bool enable, tBTM_INQ_RESULTS_CB* p_results_cb) {}
void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK* p_vsc_cback) {}
uint8_t BTM_GetAcceptlistSize() { return 0; }
+tBTM_STATUS BTM_WriteEIR(BT_HDR* p_buff) { return BTM_SUCCESS; }
+
struct btm_client_interface_t btm_client_interface = {
.eir =
{
.BTM_GetEirSupportedServices = BTM_GetEirSupportedServices,
+ .BTM_WriteEIR = BTM_WriteEIR,
},
};
diff --git a/system/test/mock/mock_stack_btm_inq.cc b/system/test/mock/mock_stack_btm_inq.cc
index 1d1c8e25ee..c068026118 100644
--- a/system/test/mock/mock_stack_btm_inq.cc
+++ b/system/test/mock/mock_stack_btm_inq.cc
@@ -109,10 +109,6 @@ tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb,
mock_function_count_map[__func__]++;
return BTM_SUCCESS;
}
-tBTM_STATUS BTM_WriteEIR(BT_HDR* p_buff) {
- mock_function_count_map[__func__]++;
- return BTM_SUCCESS;
-}
tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda, uint8_t origin,
uint64_t timeout_ms, tBTM_CMPL_CB* p_cb) {
mock_function_count_map[__func__]++;