diff options
22 files changed, 288 insertions, 153 deletions
diff --git a/android/app/aidl/android/bluetooth/IBluetooth.aidl b/android/app/aidl/android/bluetooth/IBluetooth.aidl index 6493df07ec..c1d344074e 100644 --- a/android/app/aidl/android/bluetooth/IBluetooth.aidl +++ b/android/app/aidl/android/bluetooth/IBluetooth.aidl @@ -250,9 +250,9 @@ interface IBluetooth boolean removeActiveDevice(in int profiles, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") - boolean registerBluetoothConnectionCallback(in IBluetoothConnectionCallback callback, in AttributionSource attributionSource); + oneway void registerBluetoothConnectionCallback(in IBluetoothConnectionCallback callback, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") - boolean unregisterBluetoothConnectionCallback(in IBluetoothConnectionCallback callback, in AttributionSource attributionSource); + oneway void unregisterBluetoothConnectionCallback(in IBluetoothConnectionCallback callback, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") boolean canBondWithoutDialog(in BluetoothDevice device, in AttributionSource attributionSource); diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java index 4fd31d6598..727400cb3a 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java @@ -3346,32 +3346,31 @@ public class AdapterService extends Service { } @Override - public boolean registerBluetoothConnectionCallback( + public void registerBluetoothConnectionCallback( IBluetoothConnectionCallback callback, AttributionSource source) { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser( service, TAG, "registerBluetoothConnectionCallback") || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { - return false; + return; } enforceBluetoothPrivilegedPermission(service); service.mBluetoothConnectionCallbacks.add(callback); - return true; } @Override - public boolean unregisterBluetoothConnectionCallback( + public void unregisterBluetoothConnectionCallback( IBluetoothConnectionCallback callback, AttributionSource source) { AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser( service, TAG, "unregisterBluetoothConnectionCallback") || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) { - return false; + return; } enforceBluetoothPrivilegedPermission(service); - return service.mBluetoothConnectionCallbacks.remove(callback); + service.mBluetoothConnectionCallbacks.remove(callback); } @Override diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppPreference.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppPreference.java index 521a1fe420..7171b1c035 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppPreference.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppPreference.java @@ -33,6 +33,7 @@ package com.android.bluetooth.opp; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothUtils; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; @@ -100,27 +101,16 @@ public class BluetoothOppPreference { } private String getChannelKey(BluetoothDevice remoteDevice, int uuid) { - String identityAddress = - Flags.identityAddressNullIfUnknown() - ? Utils.getBrEdrAddress(remoteDevice) - : remoteDevice.getIdentityAddress(); - return identityAddress + "_" + Integer.toHexString(uuid); + return getBrEdrAddress(remoteDevice) + "_" + Integer.toHexString(uuid); } public String getName(BluetoothDevice remoteDevice) { - String identityAddress = - Flags.identityAddressNullIfUnknown() - ? Utils.getBrEdrAddress(remoteDevice) - : remoteDevice.getIdentityAddress(); + String identityAddress = getBrEdrAddress(remoteDevice); if (identityAddress != null && identityAddress.equals("FF:FF:FF:00:00:00")) { return "localhost"; } if (!mNames.isEmpty()) { - String name = - mNames.get( - Flags.identityAddressNullIfUnknown() - ? Utils.getBrEdrAddress(remoteDevice) - : remoteDevice.getIdentityAddress()); + String name = mNames.get(identityAddress); if (name != null) { return name; } @@ -134,30 +124,40 @@ public class BluetoothOppPreference { Integer channel = null; if (mChannels != null) { channel = mChannels.get(key); - Log.v(TAG, - "getChannel for " + remoteDevice.getIdentityAddress() + "_" - + Integer.toHexString(uuid) + " as " + channel); + Log.v( + TAG, + "getChannel for " + + BluetoothUtils.toAnonymizedAddress(getBrEdrAddress(remoteDevice)) + + "_" + + Integer.toHexString(uuid) + + " as " + + channel); } return (channel != null) ? channel : -1; } public void setName(BluetoothDevice remoteDevice, String name) { - Log.v(TAG, "Setname for " + remoteDevice.getIdentityAddress() + " to " + name); + String brEdrAddress = getBrEdrAddress(remoteDevice); + Log.v( + TAG, + "Setname for " + BluetoothUtils.toAnonymizedAddress(brEdrAddress) + " to " + name); if (name != null && !name.equals(getName(remoteDevice))) { Editor ed = mNamePreference.edit(); - String address = - Flags.identityAddressNullIfUnknown() - ? Utils.getBrEdrAddress(remoteDevice) - : remoteDevice.getIdentityAddress(); - ed.putString(address, name); + ed.putString(brEdrAddress, name); ed.apply(); - mNames.put(address, name); + mNames.put(brEdrAddress, name); } } public void setChannel(BluetoothDevice remoteDevice, int uuid, int channel) { - Log.v(TAG, "Setchannel for " + remoteDevice.getIdentityAddress() + "_" - + Integer.toHexString(uuid) + " to " + channel); + Log.v( + TAG, + "Setchannel for " + + BluetoothUtils.toAnonymizedAddress(getBrEdrAddress(remoteDevice)) + + "_" + + Integer.toHexString(uuid) + + " to " + + channel); if (channel != getChannel(remoteDevice, uuid)) { String key = getChannelKey(remoteDevice, uuid); Editor ed = mChannelPreference.edit(); @@ -177,10 +177,7 @@ public class BluetoothOppPreference { public void removeName(BluetoothDevice remoteDevice) { Editor ed = mNamePreference.edit(); - String key = - Flags.identityAddressNullIfUnknown() - ? Utils.getBrEdrAddress(remoteDevice) - : remoteDevice.getIdentityAddress(); + String key = getBrEdrAddress(remoteDevice); ed.remove(key); ed.apply(); mNames.remove(key); @@ -192,4 +189,11 @@ public class BluetoothOppPreference { Log.d(TAG, "Dumping Channels: "); Log.d(TAG, mChannels.toString()); } + + private String getBrEdrAddress(BluetoothDevice device) { + if (Flags.identityAddressNullIfUnknown()) { + return Utils.getBrEdrAddress(device); + } + return device.getIdentityAddress(); + } } diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiver.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiver.java index 779cb14275..4910cf0a6f 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiver.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiver.java @@ -37,6 +37,7 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevicePicker; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProtoEnums; +import android.bluetooth.BluetoothUtils; import android.content.BroadcastReceiver; import android.content.ContentValues; import android.content.Context; @@ -79,7 +80,10 @@ public class BluetoothOppReceiver extends BroadcastReceiver { Log.d( TAG, "Received BT device selected intent, bt device: " - + remoteDevice.getIdentityAddress()); + + BluetoothUtils.toAnonymizedAddress( + Flags.identityAddressNullIfUnknown() + ? Utils.getBrEdrAddress(remoteDevice) + : remoteDevice.getIdentityAddress())); // Insert transfer session record to database mOppManager.startTransfer(remoteDevice); diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java index 7711b82d5c..349fb431b4 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java @@ -38,6 +38,7 @@ import android.bluetooth.BluetoothDevicePicker; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.BluetoothSocket; +import android.bluetooth.BluetoothUtils; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.ContentValues; @@ -62,6 +63,7 @@ import com.android.bluetooth.BluetoothObexTransport; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.IObexConnectionHandler; import com.android.bluetooth.ObexServerSockets; +import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; @@ -1307,13 +1309,15 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti @Override public boolean onConnect(BluetoothDevice device, BluetoothSocket socket) { - Log.d( TAG, " onConnect BluetoothSocket :" + socket + " \n :device :" - + device.getIdentityAddress()); + + BluetoothUtils.toAnonymizedAddress( + Flags.identityAddressNullIfUnknown() + ? Utils.getBrEdrAddress(device) + : device.getIdentityAddress())); if (!mAcceptNewConnections) { Log.d(TAG, " onConnect BluetoothSocket :" + socket + " rejected"); return false; diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java index ffad32fd22..ebecc663b8 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java @@ -40,6 +40,7 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothProtoEnums; import android.bluetooth.BluetoothSocket; +import android.bluetooth.BluetoothUtils; import android.bluetooth.BluetoothUuid; import android.bluetooth.SdpOppOpsRecord; import android.content.BroadcastReceiver; @@ -61,6 +62,7 @@ import com.android.bluetooth.BluetoothObexTransport; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; +import com.android.bluetooth.flags.Flags; import com.android.internal.annotations.VisibleForTesting; import com.android.obex.ObexTransport; @@ -130,7 +132,7 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch Log.e( TAG, "device : " - + device.getIdentityAddress() + + BluetoothUtils.toAnonymizedAddress(getBrEdrAddress(device)) + " mBatch :" + mBatch + " mCurrentShare :" @@ -147,7 +149,7 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch Log.v( TAG, "Device :" - + device.getIdentityAddress() + + BluetoothUtils.toAnonymizedAddress(getBrEdrAddress(device)) + "- OPP device: " + mBatch.mDestination + " \n mCurrentShare.mConfirm == " @@ -190,8 +192,8 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch 3); return; } - String deviceIdentityAddress = device.getIdentityAddress(); - String transferDeviceIdentityAddress = mDevice.getIdentityAddress(); + String deviceIdentityAddress = getBrEdrAddress(device); + String transferDeviceIdentityAddress = getBrEdrAddress(mDevice); if (deviceIdentityAddress == null || transferDeviceIdentityAddress == null || !deviceIdentityAddress.equalsIgnoreCase( transferDeviceIdentityAddress)) { @@ -1015,4 +1017,11 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch } } } + + private String getBrEdrAddress(BluetoothDevice device) { + if (Flags.identityAddressNullIfUnknown()) { + return Utils.getBrEdrAddress(device); + } + return device.getIdentityAddress(); + } } diff --git a/android/app/src/com/android/bluetooth/sdp/SdpManager.java b/android/app/src/com/android/bluetooth/sdp/SdpManager.java index bcd0402e15..5d7aeaeca4 100644 --- a/android/app/src/com/android/bluetooth/sdp/SdpManager.java +++ b/android/app/src/com/android/bluetooth/sdp/SdpManager.java @@ -195,7 +195,7 @@ public class SdpManager { switch (msg.what) { case MESSAGE_SDP_INTENT: SdpSearchInstance msgObj = (SdpSearchInstance) msg.obj; - Log.w(TAG, "Search timedout for UUID " + msgObj.getUuid()); + Log.w(TAG, "Search timed out for UUID " + msgObj.getUuid()); synchronized (TRACKER_LOCK) { sendSdpIntent(msgObj, null, false); } @@ -216,10 +216,18 @@ public class SdpManager { } } - - void sdpMasRecordFoundCallback(int status, byte[] address, byte[] uuid, int masInstanceId, - int l2capPsm, int rfcommCannelNumber, int profileVersion, int supportedFeatures, - int supportedMessageTypes, String serviceName, boolean moreResults) { + void sdpMasRecordFoundCallback( + int status, + byte[] address, + byte[] uuid, + int masInstanceId, + int l2capPsm, + int rfcommChannelNumber, + int profileVersion, + int supportedFeatures, + int supportedMessageTypes, + String serviceName, + boolean moreResults) { synchronized (TRACKER_LOCK) { SdpSearchInstance inst = mSdpSearchTracker.getSearchInstance(address, uuid); @@ -230,8 +238,15 @@ public class SdpManager { } inst.setStatus(status); if (status == AbstractionLayer.BT_STATUS_SUCCESS) { - sdpRecord = new SdpMasRecord(masInstanceId, l2capPsm, rfcommCannelNumber, - profileVersion, supportedFeatures, supportedMessageTypes, serviceName); + sdpRecord = + new SdpMasRecord( + masInstanceId, + l2capPsm, + rfcommChannelNumber, + profileVersion, + supportedFeatures, + supportedMessageTypes, + serviceName); } Log.d(TAG, "UUID: " + Arrays.toString(uuid)); Log.d(TAG, "UUID in parcel: " + ((Utils.byteArrayToUuid(uuid))[0]).toString()); @@ -239,8 +254,15 @@ public class SdpManager { } } - void sdpMnsRecordFoundCallback(int status, byte[] address, byte[] uuid, int l2capPsm, - int rfcommCannelNumber, int profileVersion, int supportedFeatures, String serviceName, + void sdpMnsRecordFoundCallback( + int status, + byte[] address, + byte[] uuid, + int l2capPsm, + int rfcommChannelNumber, + int profileVersion, + int supportedFeatures, + String serviceName, boolean moreResults) { synchronized (TRACKER_LOCK) { SdpSearchInstance inst = mSdpSearchTracker.getSearchInstance(address, uuid); @@ -251,8 +273,13 @@ public class SdpManager { } inst.setStatus(status); if (status == AbstractionLayer.BT_STATUS_SUCCESS) { - sdpRecord = new SdpMnsRecord(l2capPsm, rfcommCannelNumber, profileVersion, - supportedFeatures, serviceName); + sdpRecord = + new SdpMnsRecord( + l2capPsm, + rfcommChannelNumber, + profileVersion, + supportedFeatures, + serviceName); } Log.d(TAG, "UUID: " + Arrays.toString(uuid)); Log.d(TAG, "UUID in parcel: " + ((Utils.byteArrayToUuid(uuid))[0]).toString()); @@ -260,9 +287,17 @@ public class SdpManager { } } - void sdpPseRecordFoundCallback(int status, byte[] address, byte[] uuid, int l2capPsm, - int rfcommCannelNumber, int profileVersion, int supportedFeatures, - int supportedRepositories, String serviceName, boolean moreResults) { + void sdpPseRecordFoundCallback( + int status, + byte[] address, + byte[] uuid, + int l2capPsm, + int rfcommChannelNumber, + int profileVersion, + int supportedFeatures, + int supportedRepositories, + String serviceName, + boolean moreResults) { synchronized (TRACKER_LOCK) { SdpSearchInstance inst = mSdpSearchTracker.getSearchInstance(address, uuid); SdpPseRecord sdpRecord = null; @@ -272,8 +307,14 @@ public class SdpManager { } inst.setStatus(status); if (status == AbstractionLayer.BT_STATUS_SUCCESS) { - sdpRecord = new SdpPseRecord(l2capPsm, rfcommCannelNumber, profileVersion, - supportedFeatures, supportedRepositories, serviceName); + sdpRecord = + new SdpPseRecord( + l2capPsm, + rfcommChannelNumber, + profileVersion, + supportedFeatures, + supportedRepositories, + serviceName); } Log.d(TAG, "UUID: " + Arrays.toString(uuid)); Log.d(TAG, "UUID in parcel: " + ((Utils.byteArrayToUuid(uuid))[0]).toString()); @@ -281,8 +322,15 @@ public class SdpManager { } } - void sdpOppOpsRecordFoundCallback(int status, byte[] address, byte[] uuid, int l2capPsm, - int rfcommCannelNumber, int profileVersion, String serviceName, byte[] formatsList, + void sdpOppOpsRecordFoundCallback( + int status, + byte[] address, + byte[] uuid, + int l2capPsm, + int rfcommChannelNumber, + int profileVersion, + String serviceName, + byte[] formatsList, boolean moreResults) { synchronized (TRACKER_LOCK) { @@ -295,8 +343,13 @@ public class SdpManager { } inst.setStatus(status); if (status == AbstractionLayer.BT_STATUS_SUCCESS) { - sdpRecord = new SdpOppOpsRecord(serviceName, rfcommCannelNumber, l2capPsm, - profileVersion, formatsList); + sdpRecord = + new SdpOppOpsRecord( + serviceName, + rfcommChannelNumber, + l2capPsm, + profileVersion, + formatsList); } Log.d(TAG, "UUID: " + Arrays.toString(uuid)); Log.d(TAG, "UUID in parcel: " + ((Utils.byteArrayToUuid(uuid))[0]).toString()); @@ -304,8 +357,14 @@ public class SdpManager { } } - void sdpSapsRecordFoundCallback(int status, byte[] address, byte[] uuid, int rfcommCannelNumber, - int profileVersion, String serviceName, boolean moreResults) { + void sdpSapsRecordFoundCallback( + int status, + byte[] address, + byte[] uuid, + int rfcommChannelNumber, + int profileVersion, + String serviceName, + boolean moreResults) { synchronized (TRACKER_LOCK) { SdpSearchInstance inst = mSdpSearchTracker.getSearchInstance(address, uuid); @@ -316,7 +375,7 @@ public class SdpManager { } inst.setStatus(status); if (status == AbstractionLayer.BT_STATUS_SUCCESS) { - sdpRecord = new SdpSapsRecord(rfcommCannelNumber, profileVersion, serviceName); + sdpRecord = new SdpSapsRecord(rfcommChannelNumber, profileVersion, serviceName); } Log.d(TAG, "UUID: " + Arrays.toString(uuid)); Log.d(TAG, "UUID in parcel: " + ((Utils.byteArrayToUuid(uuid))[0]).toString()); diff --git a/flags/aconfig.gni b/flags/aconfig.gni index 4891c9f2cb..2f5c2a1eb0 100644 --- a/flags/aconfig.gni +++ b/flags/aconfig.gni @@ -20,21 +20,16 @@ # sources: aconfig source files # package: aconfig package template("aconfig") { - forward_variables_from(invoker, - [ - "sources", - "package", - ]) - assert(defined(sources), "sources must be set") - assert(defined(package), "package must be set") + assert(defined(invoker.sources), "sources must be set") + assert(defined(invoker.package), "package must be set") outdir = rebase_path(target_gen_dir) - aconfig_cpp_file_name = string_replace(package, ".", "_") + aconfig_cpp_file_name = string_replace(invoker.package, ".", "_") aconfig_declarations = [] - foreach(source, sources) { + foreach(source, invoker.sources) { source = rebase_path(source) aconfig_declarations += [ "--declarations=${source}" ] } @@ -46,10 +41,11 @@ template("aconfig") { args = [ "aconfig", "create-cache", - "--package=${package}", + "--package=${invoker.package}", "--cache=${outdir}/${aconfig_cache}", ] + aconfig_declarations + sources = invoker.sources outputs = [ "${outdir}/${aconfig_cache}" ] } @@ -76,7 +72,6 @@ template("aconfig") { } static_library(target_name) { - sources = [] sources = [ "${outdir}/${aconfig_cpp_file_name}.cc" ] deps = [ ":${target_name}_cpp" ] + invoker.deps all_dependent_configs = [ ":${all_dependent_config_name}" ] diff --git a/flags/system_service.aconfig b/flags/system_service.aconfig index 0ef7c502fc..a62c58f041 100644 --- a/flags/system_service.aconfig +++ b/flags/system_service.aconfig @@ -32,3 +32,13 @@ flag { } bug: "338079154" } + +flag { + name: "audio_port_binder_inherit_rt" + namespace: "bluetooth" + description: "Allow audio port AIDL thread to inherit thread priority from its caller" + bug: "335049159" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java index 2a1e654b7d..9c53e4d986 100644 --- a/framework/java/android/bluetooth/BluetoothAdapter.java +++ b/framework/java/android/bluetooth/BluetoothAdapter.java @@ -4804,28 +4804,28 @@ public final class BluetoothAdapter { } synchronized (mBluetoothConnectionCallbackExecutorMap) { - // If the callback map is empty, we register the service-to-app callback + if (mBluetoothConnectionCallbackExecutorMap.containsKey(callback)) { + throw new IllegalArgumentException("This callback has already been registered"); + } + if (mBluetoothConnectionCallbackExecutorMap.isEmpty()) { + // If the callback map is empty, we register the service-to-app callback mServiceLock.readLock().lock(); try { - if (mService != null) { - if (!mService.registerBluetoothConnectionCallback( - mConnectionCallback, mAttributionSource)) { - return false; - } + if (mService == null) { + return false; } + mService.registerBluetoothConnectionCallback( + mConnectionCallback, mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - mBluetoothConnectionCallbackExecutorMap.remove(callback); + return false; } finally { mServiceLock.readLock().unlock(); } } // Adds the passed in callback to our map of callbacks to executors - if (mBluetoothConnectionCallbackExecutorMap.containsKey(callback)) { - throw new IllegalArgumentException("This callback has already been registered"); - } mBluetoothConnectionCallbackExecutorMap.put(callback, executor); } @@ -4854,29 +4854,30 @@ public final class BluetoothAdapter { } synchronized (mBluetoothConnectionCallbackExecutorMap) { - if (mBluetoothConnectionCallbackExecutorMap.remove(callback) != null) { - return false; + if (!mBluetoothConnectionCallbackExecutorMap.containsKey(callback)) { + return true; } - } - if (!mBluetoothConnectionCallbackExecutorMap.isEmpty()) { - return true; - } + mBluetoothConnectionCallbackExecutorMap.remove(callback); - // If the callback map is empty, we unregister the service-to-app callback - mServiceLock.readLock().lock(); - try { - if (mService != null) { - return mService.unregisterBluetoothConnectionCallback( - mConnectionCallback, mAttributionSource); + if (mBluetoothConnectionCallbackExecutorMap.isEmpty()) { + // If the callback map is empty, we unregister the service-to-app callback + mServiceLock.readLock().lock(); + try { + if (mService == null) { + return true; + } + mService.unregisterBluetoothConnectionCallback( + mConnectionCallback, mAttributionSource); + } catch (RemoteException e) { + Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); + } finally { + mServiceLock.readLock().unlock(); + } } - } catch (RemoteException e) { - Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); - } finally { - mServiceLock.readLock().unlock(); } - return false; + return true; } /** diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java index c125b0e043..be680a9298 100644 --- a/framework/java/android/bluetooth/BluetoothDevice.java +++ b/framework/java/android/bluetooth/BluetoothDevice.java @@ -797,12 +797,14 @@ public final class BluetoothDevice implements Parcelable, Attributable { * Specify the exclusive manager app for this BluetoothDevice. * * <p>If there's a manager app specified for this BluetoothDevice, and the app is currently - * installed on the device, that manager app shall be responsible for providing the + * installed and enabled on the device, that manager app shall be responsible for providing the * BluetoothDevice management functionality (e.g. connect, disconnect, forget, etc.). Android - * Settings app shall not provide any management functionality for such BluetoothDevice. + * Settings app or Quick Settings System UI shall not provide any management functionality for + * such BluetoothDevice. * - * <p>Data type should be a {@link String} representing the package name of the app (e.g. - * "com.android.settings"), provided as a {@link Byte} array. + * <p>Data type should be a {@link String} representation of the {@link ComponentName} (e.g. + * "com.android.settings/.SettingsActivity") or the package name (e.g. "com.android.settings") + * of the exclusive manager, provided as a {@link Byte} array. * * @hide */ diff --git a/system/audio/Android.bp b/system/audio/Android.bp index f41e44ca40..0e957a4a28 100644 --- a/system/audio/Android.bp +++ b/system/audio/Android.bp @@ -29,8 +29,10 @@ cc_library_static { shared_libs: [ "libchrome", "liblog", + "server_configurable_flags", ], static_libs: [ + "bluetooth_flags_c_lib", "libbase", "libbluetooth_hci_pdl", "libbluetooth_log", @@ -64,7 +66,11 @@ cc_library_host_shared { header_libs: [ "libbluetooth_headers", ], + shared_libs: [ + "server_configurable_flags", + ], static_libs: [ + "bluetooth_flags_c_lib", "libbase", "libbluetooth_hci_pdl", "libbluetooth_log", diff --git a/system/audio/BUILD.gn b/system/audio/BUILD.gn index f642c65d26..e7d92ec5f7 100644 --- a/system/audio/BUILD.gn +++ b/system/audio/BUILD.gn @@ -30,6 +30,7 @@ source_set("libbt-audio-asrc") { ] deps = [ + "//bt/flags:bluetooth_flags_c_lib", "//bt/system/gd:gd_default_deps" ] } diff --git a/system/audio/asrc/asrc_resampler.cc b/system/audio/asrc/asrc_resampler.cc index 0176c0dcee..ed2c4cbcb4 100644 --- a/system/audio/asrc/asrc_resampler.cc +++ b/system/audio/asrc/asrc_resampler.cc @@ -18,6 +18,7 @@ #include <base/strings/stringprintf.h> #include <bluetooth/log.h> +#include <com_android_bluetooth_flags.h> #include <algorithm> #include <cmath> @@ -167,19 +168,35 @@ class SourceAudioHalAsrc::ClockRecovery } public: - ClockRecovery() : state_{.id = StateId::RESET}, reference_timing_{0, 0, 0} { - read_clock_timer_.SchedulePeriodic( - get_main_thread()->GetWeakPtr(), FROM_HERE, - base::BindRepeating( - [](void*) { - bluetooth::shim::GetHciLayer()->EnqueueCommand( - bluetooth::hci::ReadClockBuilder::Create( - 0, bluetooth::hci::WhichClock::LOCAL), - get_main_thread()->BindOnce( - [](bluetooth::hci::CommandCompleteView) {})); - }, - nullptr), - std::chrono::milliseconds(100)); + ClockRecovery(bluetooth::common::MessageLoopThread* thread) + : state_{.id = StateId::RESET}, reference_timing_{0, 0, 0} { + if (com::android::bluetooth::flags::run_clock_recovery_in_worker_thread()) { + read_clock_timer_.SchedulePeriodic( + thread->GetWeakPtr(), FROM_HERE, + base::BindRepeating( + [](void*) { + bluetooth::shim::GetHciLayer()->EnqueueCommand( + bluetooth::hci::ReadClockBuilder::Create( + 0, bluetooth::hci::WhichClock::LOCAL), + get_main_thread()->BindOnce( + [](bluetooth::hci::CommandCompleteView) {})); + }, + nullptr), + std::chrono::milliseconds(100)); + } else { + read_clock_timer_.SchedulePeriodic( + get_main_thread()->GetWeakPtr(), FROM_HERE, + base::BindRepeating( + [](void*) { + bluetooth::shim::GetHciLayer()->EnqueueCommand( + bluetooth::hci::ReadClockBuilder::Create( + 0, bluetooth::hci::WhichClock::LOCAL), + get_main_thread()->BindOnce( + [](bluetooth::hci::CommandCompleteView) {})); + }, + nullptr), + std::chrono::milliseconds(100)); + } hal::LinkClocker::Register(this); } @@ -411,10 +428,9 @@ inline int32_t SourceAudioHalAsrc::Resampler::Filter(const int32_t* in, #endif -SourceAudioHalAsrc::SourceAudioHalAsrc(int channels, int sample_rate, - int bit_depth, int interval_us, - int num_burst_buffers, - int burst_delay_ms) +SourceAudioHalAsrc::SourceAudioHalAsrc( + bluetooth::common::MessageLoopThread* thread, int channels, int sample_rate, + int bit_depth, int interval_us, int num_burst_buffers, int burst_delay_ms) : sample_rate_(sample_rate), bit_depth_(bit_depth), interval_us_(interval_us), @@ -453,7 +469,7 @@ SourceAudioHalAsrc::SourceAudioHalAsrc(int channels, int sample_rate, // Setup modules, the 32 bits resampler is choosed over the 16 bits resampler // when the PCM bit_depth is higher than 16 bits. - clock_recovery_ = std::make_unique<ClockRecovery>(); + clock_recovery_ = std::make_unique<ClockRecovery>(thread); resamplers_ = std::make_unique<std::vector<Resampler>>(channels, bit_depth_); // Deduct from the PCM stream characteristics, the size of the pool buffers diff --git a/system/audio/asrc/asrc_resampler.h b/system/audio/asrc/asrc_resampler.h index ae9ea312cb..049bae26db 100644 --- a/system/audio/asrc/asrc_resampler.h +++ b/system/audio/asrc/asrc_resampler.h @@ -21,6 +21,8 @@ #include <memory> #include <vector> +#include "common/message_loop_thread.h" + namespace bluetooth::audio::asrc { class SourceAudioHalAsrc { @@ -36,9 +38,9 @@ class SourceAudioHalAsrc { // `burst_delay_ms` helps to ensure that the synchronization with the // transmission intervals is done. - SourceAudioHalAsrc(int channels, int sample_rate, int bit_depth, - int interval_us, int num_burst_buffers = 2, - int burst_delay_ms = 500); + SourceAudioHalAsrc(bluetooth::common::MessageLoopThread* thread, int channels, + int sample_rate, int bit_depth, int interval_us, + int num_burst_buffers = 2, int burst_delay_ms = 500); ~SourceAudioHalAsrc(); diff --git a/system/audio/asrc/asrc_resampler_test.cc b/system/audio/asrc/asrc_resampler_test.cc index 755f7d65f0..a6a02163c8 100644 --- a/system/audio/asrc/asrc_resampler_test.cc +++ b/system/audio/asrc/asrc_resampler_test.cc @@ -34,7 +34,8 @@ namespace bluetooth::audio::asrc { class SourceAudioHalAsrcTest : public SourceAudioHalAsrc { public: SourceAudioHalAsrcTest(int channels, int bitdepth) - : SourceAudioHalAsrc(channels, 48000, bitdepth, 10000) {} + : SourceAudioHalAsrc(&message_loop_thread, channels, 48000, bitdepth, + 10000) {} template <typename T> void Resample(double ratio, const T* in, size_t in_length, size_t* in_count, diff --git a/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc b/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc index 95695d03d4..b140b1f2ec 100644 --- a/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc +++ b/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.cc @@ -17,9 +17,11 @@ #include "bluetooth_audio_port_impl.h" #include <bluetooth/log.h> +#include <com_android_bluetooth_flags.h> #include <vector> +#include "android/binder_ibinder_platform.h" #include "btif/include/btif_common.h" #include "common/stop_watch_legacy.h" @@ -226,6 +228,17 @@ PresentationPosition::TimeSpec BluetoothAudioPortImpl::timespec_convert_to_hal( .tvNSec = static_cast<int64_t>(ts.tv_nsec)}; } +// Overriding create binder and inherit RT from caller. +// In our case, the caller is the AIDL session control, so we match the priority +// of the AIDL session / AudioFlinger writer thread. +ndk::SpAIBinder BluetoothAudioPortImpl::createBinder() { + auto binder = BnBluetoothAudioPort::createBinder(); + if (com::android::bluetooth::flags::audio_port_binder_inherit_rt()) { + AIBinder_setInheritRt(binder.get(), true); + } + return binder; +} + } // namespace aidl } // namespace audio } // namespace bluetooth diff --git a/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.h b/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.h index 3b5d33e659..95e0f89856 100644 --- a/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.h +++ b/system/audio_hal_interface/aidl/bluetooth_audio_port_impl.h @@ -63,8 +63,10 @@ class BluetoothAudioPortImpl : public BnBluetoothAudioPort { private: ndk::ScopedAStatus switchCodec(bool isLowLatency); + + ndk::SpAIBinder createBinder() override; }; } // namespace aidl } // namespace audio -} // namespace bluetooth
\ No newline at end of file +} // namespace bluetooth diff --git a/system/audio_hal_interface/audio_linux.h b/system/audio_hal_interface/audio_linux.h index 87537ba660..7f98eee026 100644 --- a/system/audio_hal_interface/audio_linux.h +++ b/system/audio_hal_interface/audio_linux.h @@ -78,8 +78,16 @@ typedef enum { AUDIO_USAGE_ANNOUNCEMENT = 1003, } audio_usage_t; +// Flags that never appear on their own. +enum { + AUDIO_DEVICE_BIT_IN = 0x80000000u, + AUDIO_DEVICE_BIT_DEFAULT = 0x40000000u, +}; + +// The exact device types are not of interest at the moment. typedef enum { - AUDIO_DEVICE_DEFAULT = 0, + AUDIO_DEVICE_OUT_DEFAULT = AUDIO_DEVICE_BIT_DEFAULT, + AUDIO_DEVICE_IN_DEFAULT = AUDIO_DEVICE_BIT_IN | AUDIO_DEVICE_BIT_DEFAULT, } audio_devices_t; // The "channel mask" enum is comprised of discrete channels, diff --git a/system/bta/hearing_aid/hearing_aid.cc b/system/bta/hearing_aid/hearing_aid.cc index 6699821db6..cfcb8ad80b 100644 --- a/system/bta/hearing_aid/hearing_aid.cc +++ b/system/bta/hearing_aid/hearing_aid.cc @@ -53,6 +53,7 @@ #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" #include "stack/include/l2c_api.h" // L2CAP_MIN_OFFSET +#include "stack/include/main_thread.h" #include "types/bluetooth/uuid.h" #include "types/bt_transport.h" #include "types/raw_address.h" @@ -373,6 +374,7 @@ class HearingAidImpl : public HearingAid { if (asrc == nullptr) { log::info("Configuring Asha resampler"); asrc = std::make_unique<bluetooth::audio::asrc::SourceAudioHalAsrc>( + /*thread*/ get_main_thread(), /*channels*/ 2, /*sample_rate*/ codec_in_use == CODEC_G722_24KHZ ? 24000 : 16000, /*bit_depth*/ 16, diff --git a/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc b/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc index e7ee193f08..2a0768c5c9 100644 --- a/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc +++ b/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc @@ -252,8 +252,8 @@ void SourceImpl::StartAudioTicks() { wakelock_acquire(); if (com::android::bluetooth::flags::leaudio_hal_client_asrc()) { asrc_ = std::make_unique<bluetooth::audio::asrc::SourceAudioHalAsrc>( - source_codec_config_.num_channels, source_codec_config_.sample_rate, - source_codec_config_.bits_per_sample, + worker_thread_, source_codec_config_.num_channels, + source_codec_config_.sample_rate, source_codec_config_.bits_per_sample, source_codec_config_.data_interval_us); } audio_timer_.SchedulePeriodic( diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs index 16478dbbb6..046bcc4d89 100644 --- a/system/gd/rust/linux/stack/src/bluetooth.rs +++ b/system/gd/rust/linux/stack/src/bluetooth.rs @@ -870,15 +870,23 @@ impl Bluetooth { if self.is_connectable == mode { return true; } - self.is_connectable = mode; if self.discoverable_mode != BtDiscMode::NonDiscoverable { // Discoverable always implies connectable. Don't affect the discoverable mode for now // and the connectable mode would be restored when discoverable becomes off. + self.is_connectable = mode; return true; } - self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::AdapterScanMode( - if mode { BtScanMode::Connectable } else { BtScanMode::None_ }, - )) == 0 + let status = + self.intf.lock().unwrap().set_adapter_property(BluetoothProperty::AdapterScanMode( + if mode { BtScanMode::Connectable } else { BtScanMode::None_ }, + )); + let status = BtStatus::from(status as u32); + if status != BtStatus::Success { + warn!("Failed to set connectable mode: {:?}", status); + return false; + } + self.is_connectable = mode; + return true; } /// Returns adapter's discoverable mode. @@ -1335,13 +1343,7 @@ pub(crate) trait BtifBluetoothCallbacks { fn discovery_state(&mut self, state: BtDiscoveryState) {} #[btif_callback(SspRequest)] - fn ssp_request( - &mut self, - remote_addr: RawAddress, - variant: BtSspVariant, - passkey: u32, - ) { - } + fn ssp_request(&mut self, remote_addr: RawAddress, variant: BtSspVariant, passkey: u32) {} #[btif_callback(BondState)] fn bond_state( @@ -1701,12 +1703,7 @@ impl BtifBluetoothCallbacks for Bluetooth { } } - fn ssp_request( - &mut self, - remote_addr: RawAddress, - variant: BtSspVariant, - passkey: u32, - ) { + fn ssp_request(&mut self, remote_addr: RawAddress, variant: BtSspVariant, passkey: u32) { // Accept the Just-Works pairing that we initiated, reject otherwise. if variant == BtSspVariant::Consent { let initiated_by_us = Some(remote_addr.clone()) == self.active_pairing_address; |