diff options
51 files changed, 348 insertions, 322 deletions
diff --git a/android/app/Android.bp b/android/app/Android.bp index 60abc4dd56..ae6f315ddd 100644 --- a/android/app/Android.bp +++ b/android/app/Android.bp @@ -55,7 +55,7 @@ java_library { cc_library_shared { name: "libbluetooth_jni", - defaults: ["fluoride_basic_defaults"], + defaults: ["fluoride_defaults"], srcs: ["jni/**/*.cpp"], version_script: "libbluetooth_jni.map", header_libs: [ @@ -118,6 +118,7 @@ cc_library_shared { "libchrome", "libcutils", "libevent", + "libflatbuffers-cpp", "libfmq", "libg722codec", "libhidlbase", @@ -125,6 +126,7 @@ cc_library_shared { "libmodpb64", "libopus", "libosi", + "libprotobuf-cpp-lite", "libudrv-uipc", "libutils", ], @@ -148,7 +150,7 @@ cc_library_shared { cc_library { name: "libbluetooth-core", - defaults: ["fluoride_basic_defaults"], + defaults: ["fluoride_defaults"], header_libs: [ "jni_headers", "libbluetooth_headers", @@ -199,8 +201,12 @@ android_app { srcs: [ ":statslog-bluetooth-java-gen", ":statslog-bt-restricted-java-gen", + "proto/keystore.proto", "src/**/*.java", ], + proto: { + type: "lite", + }, aaptflags: [ "--custom-package", "com.android.bluetooth", diff --git a/system/gd/proto/bluetooth/bluetoothKeystore/keystore.proto b/android/app/proto/keystore.proto index d0e418bd28..f0641ff6fa 100644 --- a/system/gd/proto/bluetooth/bluetoothKeystore/keystore.proto +++ b/android/app/proto/keystore.proto @@ -16,9 +16,6 @@ syntax = "proto2"; -// C++ namespace: bluetooth::metrics::BluetoothMetricsProto -package bluetooth.keystore.BluetoothKeystoreProto; - option java_package = "com.android.bluetooth"; option java_outer_classname = "BluetoothKeystoreProto"; diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java index 5194a7e911..0def33ca1c 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java @@ -120,6 +120,7 @@ import com.android.bluetooth.bass_client.BassClientService; import com.android.bluetooth.btservice.InteropUtil.InteropFeature; import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; import com.android.bluetooth.btservice.activityattribution.ActivityAttributionService; +import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreNativeInterface; import com.android.bluetooth.btservice.bluetoothkeystore.BluetoothKeystoreService; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.btservice.storage.MetadataDatabase; @@ -611,7 +612,9 @@ public class AdapterService extends Service { mAdapterProperties = new AdapterProperties(this); mAdapterStateMachine = new AdapterState(this, mLooper); mJniCallbacks = new JniCallbacks(this, mAdapterProperties); - mBluetoothKeystoreService = new BluetoothKeystoreService(isCommonCriteriaMode()); + mBluetoothKeystoreService = + new BluetoothKeystoreService( + new BluetoothKeystoreNativeInterface(), isCommonCriteriaMode()); mBluetoothKeystoreService.start(); int configCompareResult = mBluetoothKeystoreService.getCompareResult(); diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterState.java b/android/app/src/com/android/bluetooth/btservice/AdapterState.java index 87134e4673..ae395bf173 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterState.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterState.java @@ -77,10 +77,14 @@ final class AdapterState extends StateMachine { static final String BLE_STOP_TIMEOUT_DELAY_PROPERTY = "ro.bluetooth.ble_stop_timeout_delay"; - static final int BLE_START_TIMEOUT_DELAY = 4000; - static final int BLE_STOP_TIMEOUT_DELAY = 4000; - static final int BREDR_START_TIMEOUT_DELAY = 4000; - static final int BREDR_STOP_TIMEOUT_DELAY = 4000; + static final int BLE_START_TIMEOUT_DELAY = + 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); + static final int BLE_STOP_TIMEOUT_DELAY = + 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); + static final int BREDR_START_TIMEOUT_DELAY = + 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); + static final int BREDR_STOP_TIMEOUT_DELAY = + 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); private AdapterService mAdapterService; private TurningOnState mTurningOnState = new TurningOnState(); diff --git a/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java b/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java index a1af22f3c3..2bd4abb39b 100644 --- a/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java +++ b/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java @@ -250,6 +250,11 @@ final class BondStateMachine extends StateMachine { } break; case SSP_REQUEST: + if (devProp == null) { + errorLog("devProp is null, maybe the device is disconnected"); + break; + } + int passkey = msg.arg1; int variant = msg.arg2; boolean displayPasskey = @@ -262,6 +267,11 @@ final class BondStateMachine extends StateMachine { variant); break; case PIN_REQUEST: + if (devProp == null) { + errorLog("devProp is null, maybe the device is disconnected"); + break; + } + BluetoothClass btClass = dev.getBluetoothClass(); int btDeviceClass = btClass.getDeviceClass(); if (btDeviceClass == BluetoothClass.Device.PERIPHERAL_KEYBOARD || btDeviceClass diff --git a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java index ebee407821..0b616accaf 100644 --- a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java +++ b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java @@ -18,44 +18,27 @@ package com.android.bluetooth.btservice.bluetoothkeystore; import android.util.Log; -import com.android.internal.annotations.GuardedBy; import java.io.IOException; import java.security.NoSuchAlgorithmException; -final class BluetoothKeystoreNativeInterface { +/** Native interface to be used by BluetoothKeystoreService */ +public class BluetoothKeystoreNativeInterface { + private static final String TAG = BluetoothKeystoreNativeInterface.class.getSimpleName(); - private static final String TAG = "BluetoothKeystoreNativeInterface"; - - @GuardedBy("INSTANCE_LOCK") - private static BluetoothKeystoreNativeInterface sInstance; - private static final Object INSTANCE_LOCK = new Object(); + private BluetoothKeystoreService mBluetoothKeystoreService = null; static { classInitNative(); } - private BluetoothKeystoreNativeInterface() { - } - - /** - * Get singleton instance. - */ - public static BluetoothKeystoreNativeInterface getInstance() { - synchronized (INSTANCE_LOCK) { - if (sInstance == null) { - sInstance = new BluetoothKeystoreNativeInterface(); - } - return sInstance; - } - } - /** * Initializes the native interface. * - * priorities to configure. + * <p>priorities to configure. */ - public void init() { + public void init(BluetoothKeystoreService service) { + mBluetoothKeystoreService = service; initNative(); } @@ -64,6 +47,7 @@ final class BluetoothKeystoreNativeInterface { */ public void cleanup() { cleanupNative(); + mBluetoothKeystoreService = null; } // Callbacks from the native stack back into the Java framework. @@ -71,30 +55,36 @@ final class BluetoothKeystoreNativeInterface { // state machine the message should be routed to. private void setEncryptKeyOrRemoveKeyCallback(String prefixString, String decryptedString) { - BluetoothKeystoreService service = BluetoothKeystoreService.getBluetoothKeystoreService(); - if (service != null) { - try { - service.setEncryptKeyOrRemoveKey(prefixString, decryptedString); - } catch (InterruptedException e) { - Log.e(TAG, "Interrupted while operating."); - } catch (IOException e) { - Log.e(TAG, "IO error while file operating."); - } catch (NoSuchAlgorithmException e) { - Log.e(TAG, "encrypt could not find the algorithm: SHA256"); - } - } else { - Log.e(TAG, "Event ignored, service not available: " + prefixString); + final BluetoothKeystoreService service = mBluetoothKeystoreService; + + if (service == null) { + Log.e( + TAG, + "setEncryptKeyOrRemoveKeyCallback: Event ignored, service not available: " + + prefixString); + return; + } + + try { + service.setEncryptKeyOrRemoveKey(prefixString, decryptedString); + } catch (InterruptedException e) { + Log.e(TAG, "Interrupted while operating."); + } catch (IOException e) { + Log.e(TAG, "IO error while file operating."); + } catch (NoSuchAlgorithmException e) { + Log.e(TAG, "encrypt could not find the algorithm: SHA256"); } } private String getKeyCallback(String prefixString) { - BluetoothKeystoreService service = BluetoothKeystoreService.getBluetoothKeystoreService(); - if (service != null) { - return service.getKey(prefixString); - } else { - Log.e(TAG, "Event ignored, service not available: " + prefixString); + final BluetoothKeystoreService service = mBluetoothKeystoreService; + + if (service == null) { + Log.e(TAG, "getKeyCallback: Event ignored, service not available: " + prefixString); return null; } + + return service.getKey(prefixString); } // Native methods that call into the JNI interface diff --git a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java index 25b06c3775..743534420b 100644 --- a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java +++ b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java @@ -46,7 +46,6 @@ import java.util.Base64; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -99,7 +98,7 @@ public class BluetoothKeystoreService { private static final int CONFIG_BACKUP_COMPARE_PASS = 0b10; private int mCompareResult; - BluetoothKeystoreNativeInterface mBluetoothKeystoreNativeInterface; + private final BluetoothKeystoreNativeInterface mBluetoothKeystoreNativeInterface; private ComputeDataThread mEncryptDataThread; private ComputeDataThread mDecryptDataThread; @@ -113,8 +112,10 @@ public class BluetoothKeystoreService { private Base64.Decoder mDecoder = Base64.getDecoder(); private Base64.Encoder mEncoder = Base64.getEncoder(); - public BluetoothKeystoreService(boolean isCommonCriteriaMode) { + public BluetoothKeystoreService( + BluetoothKeystoreNativeInterface nativeInterface, boolean isCommonCriteriaMode) { debugLog("new BluetoothKeystoreService isCommonCriteriaMode: " + isCommonCriteriaMode); + mBluetoothKeystoreNativeInterface = nativeInterface; mIsCommonCriteriaMode = isCommonCriteriaMode; mCompareResult = CONFIG_COMPARE_INIT; startThread(); @@ -140,13 +141,6 @@ public class BluetoothKeystoreService { return; } - mBluetoothKeystoreNativeInterface = Objects.requireNonNull( - BluetoothKeystoreNativeInterface.getInstance(), - "BluetoothKeystoreNativeInterface cannot be null when BluetoothKeystore starts"); - - // Mark service as started - setBluetoothKeystoreService(this); - try { if (!keyStore.containsAlias(KEYALIAS) && mIsCommonCriteriaMode) { infoLog("Enable Common Criteria mode for the first time, pass hash check."); @@ -187,12 +181,9 @@ public class BluetoothKeystoreService { debugLog("cleanup() called before start()"); return; } - // Mark service as stopped - setBluetoothKeystoreService(null); // Cleanup native interface mBluetoothKeystoreNativeInterface.cleanup(); - mBluetoothKeystoreNativeInterface = null; if (mIsCommonCriteriaMode) { cleanupForCommonCriteriaModeEnable(); @@ -296,9 +287,7 @@ public class BluetoothKeystoreService { stopThread(); startThread(); // Initialize native interface - if (mBluetoothKeystoreNativeInterface != null) { - mBluetoothKeystoreNativeInterface.init(); - } + mBluetoothKeystoreNativeInterface.init(this); } private boolean isAvailable() { @@ -306,28 +295,6 @@ public class BluetoothKeystoreService { } /** - * Get the BluetoothKeystoreService instance - */ - public static synchronized BluetoothKeystoreService getBluetoothKeystoreService() { - if (sBluetoothKeystoreService == null) { - debugLog("getBluetoothKeystoreService(): service is NULL"); - return null; - } - - if (!sBluetoothKeystoreService.isAvailable()) { - debugLog("getBluetoothKeystoreService(): service is not available"); - return null; - } - return sBluetoothKeystoreService; - } - - private static synchronized void setBluetoothKeystoreService( - BluetoothKeystoreService instance) { - debugLog("setBluetoothKeystoreService(): set to: " + instance); - sBluetoothKeystoreService = instance; - } - - /** * Gets result of the checksum comparison */ public int getCompareResult() { diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java index f65ab82331..1e78e0c86b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java @@ -20,15 +20,6 @@ import android.os.Binder; import android.os.Process; import android.util.Log; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.security.NoSuchAlgorithmException; -import java.util.HashMap; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - import org.junit.After; import org.junit.Assert; import org.junit.Assume; @@ -36,12 +27,25 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @RunWith(JUnit4.class) public final class BluetoothKeystoreServiceTest { private static final String TAG = "BluetoothKeystoreServiceTest"; private BluetoothKeystoreService mBluetoothKeystoreService; + @Mock private BluetoothKeystoreNativeInterface mMockNativeInterface; + // Please also check bt_stack string configuration if you want to change the content. private static final String CONFIG_FILE_PREFIX = "bt_config-origin"; private static final String CONFIG_BACKUP_PREFIX = "bt_config-backup"; @@ -119,8 +123,9 @@ public final class BluetoothKeystoreServiceTest { @Before public void setUp() { + MockitoAnnotations.initMocks(this); Assume.assumeTrue("Ignore test when the user is not primary.", isPrimaryUser()); - mBluetoothKeystoreService = new BluetoothKeystoreService(true); + mBluetoothKeystoreService = new BluetoothKeystoreService(mMockNativeInterface, true); Assert.assertNotNull(mBluetoothKeystoreService); // backup origin config data. try { @@ -280,7 +285,7 @@ public final class BluetoothKeystoreServiceTest { mBluetoothKeystoreService.cleanupForCommonCriteriaModeEnable(); // new mBluetoothKeystoreService and the Common Criteria mode is false. - mBluetoothKeystoreService = new BluetoothKeystoreService(false); + mBluetoothKeystoreService = new BluetoothKeystoreService(mMockNativeInterface, false); Assert.assertNotNull(mBluetoothKeystoreService); mBluetoothKeystoreService.loadConfigData(); @@ -304,7 +309,7 @@ public final class BluetoothKeystoreServiceTest { mBluetoothKeystoreService.cleanupForCommonCriteriaModeDisable(); // new mBluetoothKeystoreService and the Common Criteria mode is true. - mBluetoothKeystoreService = new BluetoothKeystoreService(true); + mBluetoothKeystoreService = new BluetoothKeystoreService(mMockNativeInterface, true); mBluetoothKeystoreService.loadConfigData(); Assert.assertTrue(mBluetoothKeystoreService.getCompareResult() == 0); diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java index 953d93249a..d61d3de936 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java @@ -49,7 +49,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; - @MediumTest @RunWith(AndroidJUnit4.class) public class BluetoothOppServiceTest { @@ -90,7 +89,11 @@ public class BluetoothOppServiceTest { // Since the update thread is not run (we mocked it), it will not clean itself on interrupt // (normally, the service will wait for the update thread to clean itself after // being interrupted). We clean it manually here - mService.mUpdateThread = null; + BluetoothOppService service = mService; + if (service != null) { + service.mUpdateThread = null; + } + BluetoothMethodProxy.setInstanceForTesting(null); TestUtils.stopService(mServiceRule, BluetoothOppService.class); TestUtils.clearAdapterService(mAdapterService); @@ -187,5 +190,4 @@ public class BluetoothOppServiceTest { eq(BluetoothShare._ID + " < " + 20), any()); } -} - +}
\ No newline at end of file diff --git a/android/pandora/test/AndroidTest.xml b/android/pandora/test/AndroidTest.xml index 9906aeac75..29353f27ae 100644 --- a/android/pandora/test/AndroidTest.xml +++ b/android/pandora/test/AndroidTest.xml @@ -23,9 +23,7 @@ <option name="install-arg" value="-r" /> <option name="install-arg" value="-g" /> </target_preparer> - <target_preparer class="com.android.tradefed.targetprep.RunHostCommandTargetPreparer"> - <option name="host-setup-command" value="adb -s $SERIAL forward tcp:6211 vsock:2:7300" /> - <option name="host-teardown-command" value="adb -s $SERIAL forward --remove tcp:6211" /> + <target_preparer class="com.android.tradefed.targetprep.RootcanalForwarderPreparer"> </target_preparer> <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> <option name="run-command" value="cmd bluetooth_manager enable" /> diff --git a/android/pandora/test/config.yml b/android/pandora/test/config.yml index 3682981ff2..3dd993b15d 100644 --- a/android/pandora/test/config.yml +++ b/android/pandora/test/config.yml @@ -5,8 +5,8 @@ TestBeds: Controllers: AndroidDevice: '*' BumbleDevice: - - transport: 'tcp-client:127.0.0.1:6211' - - transport: 'tcp-client:127.0.0.1:6211' + - tcp: ${ROOTCANAL_HCI_ADDRESS} + - tcp: ${ROOTCANAL_HCI_ADDRESS} - Name: bumble.bumbles Controllers: BumbleDevice: diff --git a/framework/java/android/bluetooth/BluetoothGattServer.java b/framework/java/android/bluetooth/BluetoothGattServer.java index 05eaf1ac6a..03910657c1 100644 --- a/framework/java/android/bluetooth/BluetoothGattServer.java +++ b/framework/java/android/bluetooth/BluetoothGattServer.java @@ -668,7 +668,7 @@ public final class BluetoothGattServer implements BluetoothProfile { /** * Set the preferred connection PHY for this app. Please note that this is just a - * recommendation, whether the PHY change will happen depends on other applications peferences, + * recommendation, whether the PHY change will happen depends on other applications preferences, * local and remote controller capabilities. Controller can override these settings. <p> {@link * BluetoothGattServerCallback#onPhyUpdate} will be triggered as a result of this call, even if * no PHY change happens. It is also triggered when remote device updates the PHY. @@ -856,7 +856,7 @@ public final class BluetoothGattServer implements BluetoothProfile { /** * Add a service to the list of services to be hosted. * - * <p>Once a service has been addded to the list, the service and its + * <p>Once a service has been added to the list, the service and its * included characteristics will be provided by the local device. * * <p>If the local device has already exposed services when this function @@ -943,7 +943,7 @@ public final class BluetoothGattServer implements BluetoothProfile { /** * Returns a list of GATT services offered by this device. * - * <p>An application must call {@link #addService} to add a serice to the + * <p>An application must call {@link #addService} to add a service to the * list of services offered by this device. * * @return List of services. Returns an empty list if no services have been added yet. diff --git a/service/Android.bp b/service/Android.bp index 97715d825d..7211e68801 100644 --- a/service/Android.bp +++ b/service/Android.bp @@ -45,11 +45,6 @@ java_defaults { "-Xep:ReferenceEquality:ERROR", ], }, - product_variables: { - pdk: { - enabled: false, - }, - }, sdk_version: "system_server_current", diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java index a9c16deeb2..f95ff2ac3f 100644 --- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java +++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java @@ -67,6 +67,7 @@ import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.SystemClock; +import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.provider.DeviceConfig; @@ -113,10 +114,13 @@ class BluetoothManagerService { private static final int CRASH_LOG_MAX_SIZE = 100; private static final int DEFAULT_REBIND_COUNT = 3; - private static final int TIMEOUT_BIND_MS = 3000; // Maximum msec to wait for a bind + // Maximum msec to wait for a bind + private static final int TIMEOUT_BIND_MS = + 3000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); // Timeout value for synchronous binder call - private static final Duration SYNC_CALLS_TIMEOUT = Duration.ofSeconds(3); + private static final Duration SYNC_CALLS_TIMEOUT = + Duration.ofSeconds(3 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1)); /** * @return timeout value for synchronous binder call @@ -126,15 +130,20 @@ class BluetoothManagerService { } // Maximum msec to wait for service restart - private static final int SERVICE_RESTART_TIME_MS = 400; + private static final int SERVICE_RESTART_TIME_MS + = 400 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); // Maximum msec to wait for restart due to error - private static final int ERROR_RESTART_TIME_MS = 3000; + private static final int ERROR_RESTART_TIME_MS + = 3000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); // Maximum msec to delay MESSAGE_USER_SWITCHED - private static final int USER_SWITCHED_TIME_MS = 200; + private static final int USER_SWITCHED_TIME_MS + = 200 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); // Delay for the addProxy function in msec - private static final int ADD_PROXY_DELAY_MS = 100; + private static final int ADD_PROXY_DELAY_MS + = 100 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); // Delay for retrying enable and disable in msec - private static final int ENABLE_DISABLE_DELAY_MS = 300; + private static final int ENABLE_DISABLE_DELAY_MS + = 300 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1); @VisibleForTesting static final int MESSAGE_ENABLE = 1; @VisibleForTesting static final int MESSAGE_DISABLE = 2; diff --git a/system/audio_hal_interface/fuzzer/Android.bp b/system/audio_hal_interface/fuzzer/Android.bp index eed40552e9..0fc5e26792 100644 --- a/system/audio_hal_interface/fuzzer/Android.bp +++ b/system/audio_hal_interface/fuzzer/Android.bp @@ -77,7 +77,6 @@ cc_defaults { "libchrome", "libcutils", "libevent", - "libflatbuffers-cpp", "libg722codec", "libhidlbase", "libjsoncpp", diff --git a/system/bta/Android.bp b/system/bta/Android.bp index b2f82cb528..518161945b 100644 --- a/system/bta/Android.bp +++ b/system/bta/Android.bp @@ -9,7 +9,7 @@ package { cc_defaults { name: "fluoride_bta_defaults", - defaults: ["fluoride_basic_defaults"], + defaults: ["fluoride_defaults"], local_include_dirs: [ "dm", "hd", @@ -243,7 +243,6 @@ cc_test { "libbt-bta", "libbt-bta-core", "libbt-common", - "libbt-protos-lite", "libbtcore", "libchrome", "libcom.android.sysprop.bluetooth", @@ -289,7 +288,6 @@ cc_test { "libbt-bta", "libbt-bta-core", "libbt-common", - "libbt-protos-lite", "libbtcore", "libchrome", "libosi", @@ -404,13 +402,11 @@ cc_test { static_libs: [ "libbluetooth-types", "libbt-common", - "libbt-protos-lite", "libbtcore", "libbtdevice", "libchrome", "libcom.android.sysprop.bluetooth", "libevent", - "libflatbuffers-cpp", "libgmock", ], sanitize: { @@ -466,7 +462,6 @@ cc_test { static_libs: [ "crypto_toolbox_for_tests", "libbt-common", - "libbt-protos-lite", "libchrome", "libgmock", "libosi", @@ -510,7 +505,6 @@ cc_test { static_libs: [ "crypto_toolbox_for_tests", "libbt-common", - "libbt-protos-lite", "libchrome", "libgmock", "libosi", @@ -565,7 +559,6 @@ cc_test { static_libs: [ "crypto_toolbox_for_tests", "libbt-common", - "libbt-protos-lite", "libchrome", "libgmock", "libosi", @@ -729,7 +722,6 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libchrome", "libevent", "libflatbuffers-cpp", @@ -801,7 +793,6 @@ cc_test { "crypto_toolbox_for_tests", "libbt-audio-hal-interface", "libbt-common", - "libbt-protos-lite", "libchrome", "libevent", "libflatbuffers-cpp", @@ -864,7 +855,6 @@ cc_test { static_libs: [ "crypto_toolbox_for_tests", "libbt-common", - "libbt-protos-lite", "libchrome", "libgmock", "libosi", @@ -917,7 +907,6 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libchrome", "libgmock", "liblc3", @@ -981,7 +970,6 @@ cc_test { static_libs: [ "libbt-audio-hal-interface", "libbt-common", - "libbt-protos-lite", "libchrome", "libevent", "libgmock", @@ -1042,7 +1030,6 @@ cc_test { static_libs: [ "crypto_toolbox_for_tests", "libbt-common", - "libbt-protos-lite", "libchrome", "libgmock", ], @@ -1104,7 +1091,6 @@ cc_test { static_libs: [ "crypto_toolbox_for_tests", "libbt-common", - "libbt-protos-lite", "libchrome", "libcom.android.sysprop.bluetooth", "libevent", diff --git a/system/btcore/Android.bp b/system/btcore/Android.bp index 0361a809c0..5e4b9de0dd 100644 --- a/system/btcore/Android.bp +++ b/system/btcore/Android.bp @@ -10,7 +10,7 @@ package { cc_defaults { name: "libbtcore_defaults", - defaults: ["fluoride_basic_defaults"], + defaults: ["fluoride_defaults"], local_include_dirs: ["include"], include_dirs: [ "packages/modules/Bluetooth/system", @@ -36,7 +36,7 @@ cc_defaults { cc_library_static { name: "libbthalutils", - defaults: ["fluoride_basic_defaults"], + defaults: ["fluoride_defaults"], srcs: [ "src/hal_util.cc", ], diff --git a/system/btif/Android.bp b/system/btif/Android.bp index 2afe65c298..d7e341ed6d 100644 --- a/system/btif/Android.bp +++ b/system/btif/Android.bp @@ -39,9 +39,6 @@ cc_library { generated_sources: ["statslog_bt.cpp"], generated_headers: ["statslog_bt.h"], export_generated_headers: ["statslog_bt.h"], - shared_libs: [ - "libcutils", - ], apex_available: [ "com.android.btservices", ], @@ -57,6 +54,7 @@ cc_library { }, host: { static_libs: [ + "libbase", "libstatssocket", ], export_static_lib_headers: [ @@ -89,7 +87,7 @@ genrule { cc_library_static { name: "libbtif", - defaults: ["fluoride_basic_defaults"], + defaults: ["fluoride_defaults"], include_dirs: btifCommonIncludes, srcs: [ // AVRCP Target Service @@ -171,7 +169,7 @@ cc_library_static { cc_library_static { name: "libbtif-core", - defaults: ["fluoride_basic_defaults"], + defaults: ["fluoride_defaults"], include_dirs: btifCommonIncludes, srcs: [ // Callouts @@ -292,7 +290,6 @@ cc_test { "libbt-bta-core", "libbt-common", "libbt-hci", - "libbt-protos-lite", "libbt-sbc-decoder", "libbt-sbc-encoder", "libbt-stack", @@ -349,7 +346,6 @@ cc_test { static_libs: [ "libbluetooth-types", "libchrome", - "libflatbuffers-cpp", "libosi", ], cflags: ["-DBUILDCFG"], @@ -382,7 +378,6 @@ cc_test { static_libs: [ "libbluetooth-types", "libchrome", - "libflatbuffers-cpp", "libosi", ], cflags: ["-DBUILDCFG"], @@ -419,7 +414,6 @@ cc_test { static_libs: [ "libbluetooth-types", "libbt-common", - "libbt-protos-lite", "libchrome", "libevent", "libosi-AllocationTestHarness", @@ -613,7 +607,6 @@ cc_test { "libchrome", "libcom.android.sysprop.bluetooth", "libevent", - "libflatbuffers-cpp", "libgmock", ], cflags: ["-DBUILDCFG"], @@ -745,7 +738,6 @@ cc_test { "libchrome", "libcom.android.sysprop.bluetooth", "libevent", - "libflatbuffers-cpp", "libgmock", ], cflags: ["-DBUILDCFG"], diff --git a/system/btif/co/bta_av_co.cc b/system/btif/co/bta_av_co.cc index 42711010dc..e1724b21ea 100644 --- a/system/btif/co/bta_av_co.cc +++ b/system/btif/co/bta_av_co.cc @@ -406,13 +406,6 @@ class BtaAvCo { const tA2DP_ENCODER_INTERFACE* GetSourceEncoderInterface(); /** - * Get the Sink decoder interface for the current codec. - * - * @return the Sink decoder interface for the current codec - */ - const tA2DP_DECODER_INTERFACE* GetSinkDecoderInterface(); - - /** * Set the codec user configuration. * * @param peer_address the peer address @@ -1446,8 +1439,8 @@ void BtaAvCo::UpdateMtu(tBTA_AV_HNDL bta_av_handle, } bool BtaAvCo::SetActivePeer(const RawAddress& peer_address) { - VLOG(1) << __func__ << ": peer_address=" - << ADDRESS_TO_LOGGABLE_STR(peer_address); + LOG(INFO) << __func__ + << ": peer_address=" << ADDRESS_TO_LOGGABLE_STR(peer_address); std::lock_guard<std::recursive_mutex> lock(codec_lock_); @@ -1505,12 +1498,6 @@ const tA2DP_ENCODER_INTERFACE* BtaAvCo::GetSourceEncoderInterface() { return A2DP_GetEncoderInterface(codec_config_); } -const tA2DP_DECODER_INTERFACE* BtaAvCo::GetSinkDecoderInterface() { - std::lock_guard<std::recursive_mutex> lock(codec_lock_); - - return A2DP_GetDecoderInterface(codec_config_); -} - bool BtaAvCo::SetCodecUserConfig( const RawAddress& peer_address, const btav_a2dp_codec_config_t& codec_user_config, bool* p_restart_output) { @@ -2263,10 +2250,6 @@ const tA2DP_ENCODER_INTERFACE* bta_av_co_get_encoder_interface(void) { return bta_av_co_cb.GetSourceEncoderInterface(); } -const tA2DP_DECODER_INTERFACE* bta_av_co_get_decoder_interface(void) { - return bta_av_co_cb.GetSinkDecoderInterface(); -} - bool bta_av_co_set_codec_user_config( const RawAddress& peer_address, const btav_a2dp_codec_config_t& codec_user_config, bool* p_restart_output) { diff --git a/system/btif/include/btif_av_co.h b/system/btif/include/btif_av_co.h index 1ce810f5e3..d7f80ab559 100644 --- a/system/btif/include/btif_av_co.h +++ b/system/btif/include/btif_av_co.h @@ -40,12 +40,6 @@ void bta_av_co_get_peer_params(const RawAddress& peer_addr, // otherwise NULL. const tA2DP_ENCODER_INTERFACE* bta_av_co_get_encoder_interface(void); -// Gets the current A2DP decoder interface that can be used to decode received -// A2DP packets - see |tA2DP_DECODER_INTERFACE|. -// Returns the A2DP decoder interface if the current codec is setup, otherwise -// NULL. -const tA2DP_DECODER_INTERFACE* bta_av_co_get_decoder_interface(void); - // Sets the user preferred codec configuration. // The peer address is |peer_addr|. // |codec_user_config| contains the preferred codec configuration. diff --git a/system/btif/src/btif_a2dp_sink.cc b/system/btif/src/btif_a2dp_sink.cc index 9a03a3cd44..4340e48375 100644 --- a/system/btif/src/btif_a2dp_sink.cc +++ b/system/btif/src/btif_a2dp_sink.cc @@ -631,7 +631,8 @@ static void btif_a2dp_sink_decoder_update_event( btif_a2dp_sink_cb.rx_flush = false; APPL_TRACE_DEBUG("%s: reset to Sink role", __func__); - btif_a2dp_sink_cb.decoder_interface = bta_av_co_get_decoder_interface(); + btif_a2dp_sink_cb.decoder_interface = + A2DP_GetDecoderInterface(p_buf->codec_info); if (btif_a2dp_sink_cb.decoder_interface == nullptr) { LOG_ERROR("%s: cannot stream audio: no source decoder interface", __func__); return; diff --git a/system/btif/src/btif_av.cc b/system/btif/src/btif_av.cc index 767279e724..23f78fd1e8 100644 --- a/system/btif/src/btif_av.cc +++ b/system/btif/src/btif_av.cc @@ -4035,9 +4035,9 @@ uint8_t btif_av_get_peer_sep(void) { } uint8_t peer_sep = peer->PeerSep(); - LOG_INFO("Peer %s SEP is %s (%d)", - ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), - (peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink", peer_sep); + BTIF_TRACE_DEBUG("Peer %s SEP is %s (%d)", + ADDRESS_TO_LOGGABLE_CSTR(peer->PeerAddress()), + (peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink", peer_sep); return peer_sep; } diff --git a/system/btif/src/btif_avrcp_audio_track.cc b/system/btif/src/btif_avrcp_audio_track.cc index 296c603c7f..2a732f372e 100644 --- a/system/btif/src/btif_avrcp_audio_track.cc +++ b/system/btif/src/btif_avrcp_audio_track.cc @@ -51,8 +51,8 @@ constexpr float kMinTrackGain = 0.0f; void* BtifAvrcpAudioTrackCreate(int trackFreq, int bitsPerSample, int channelCount) { - LOG_VERBOSE("%s Track.cpp: btCreateTrack freq %d bps %d channel %d ", - __func__, trackFreq, bitsPerSample, channelCount); + LOG_INFO("%s Track.cpp: btCreateTrack freq %d bps %d channel %d ", __func__, + trackFreq, bitsPerSample, channelCount); AAudioStreamBuilder* builder; AAudioStream* stream; diff --git a/system/build/Android.bp b/system/build/Android.bp index 96838d1771..76b9b476f3 100644 --- a/system/build/Android.bp +++ b/system/build/Android.bp @@ -69,7 +69,6 @@ cc_defaults { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libcutils", "libgmock", "libosi", @@ -84,18 +83,6 @@ cc_defaults { } cc_defaults { - name: "fluoride_basic_defaults", - defaults: [ - "fluoride_defaults", - ], - static_libs: [ - "libbt-protos-lite", - "libflatbuffers-cpp", - "libprotobuf-cpp-lite", - ], -} - -cc_defaults { name: "fluoride_defaults", defaults: [ "fluoride_defaults_fuzzable", diff --git a/system/common/Android.bp b/system/common/Android.bp index 6a63e14de7..c40182d5b7 100644 --- a/system/common/Android.bp +++ b/system/common/Android.bp @@ -10,7 +10,7 @@ package { cc_library_static { name: "libbt-common", defaults: [ - "fluoride_basic_defaults", + "fluoride_defaults", ], host_supported: true, include_dirs: [ @@ -28,9 +28,17 @@ cc_library_static { "stop_watch_legacy.cc", "time_util.cc", ], + proto: { + type: "lite", + canonical_path_from_root: false, + export_proto_headers: true, + }, target: { android: { - srcs: ["metrics.cc"], + srcs: [ + ":bluetooth-metrics-proto", + "metrics.cc", + ], }, host: { srcs: ["metrics_linux.cc"], @@ -88,7 +96,6 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libchrome", "libevent", "libgmock", diff --git a/system/device/Android.bp b/system/device/Android.bp index 8a57219a8e..33a04833b0 100644 --- a/system/device/Android.bp +++ b/system/device/Android.bp @@ -10,7 +10,7 @@ package { cc_library_static { name: "libbtdevice", - defaults: ["fluoride_basic_defaults"], + defaults: ["fluoride_defaults"], host_supported: true, local_include_dirs: [ "include", diff --git a/system/gd/Android.bp b/system/gd/Android.bp index 753c1bd8f4..70e52fe37e 100644 --- a/system/gd/Android.bp +++ b/system/gd/Android.bp @@ -162,6 +162,9 @@ cc_defaults { "libcrypto", "libflatbuffers-cpp", ], + export_shared_lib_headers: [ + "libflatbuffers-cpp", + ], whole_static_libs: [ "libc++fs", ], @@ -468,7 +471,6 @@ cc_defaults { ], shared_libs: [ "libcrypto", - "libflatbuffers-cpp", "libgrpc++", "libgrpc_wrap", ], diff --git a/system/gd/proto/Android.bp b/system/gd/proto/Android.bp index 538d8df347..6136cf84f6 100644 --- a/system/gd/proto/Android.bp +++ b/system/gd/proto/Android.bp @@ -14,7 +14,6 @@ java_library_static { type: "lite", }, srcs: [ - "bluetooth/bluetoothKeystore/keystore.proto", "bluetooth/metrics/bluetooth.proto", ], apex_available: [ @@ -24,21 +23,11 @@ java_library_static { sdk_version: "current", } -cc_library_static { - name: "libbt-protos-lite", - host_supported: true, - proto: { - export_proto_headers: true, - type: "lite", - }, +filegroup { + name: "bluetooth-metrics-proto", srcs: [ - "bluetooth/bluetoothKeystore/keystore.proto", "bluetooth/metrics/bluetooth.proto", ], - apex_available: [ - "com.android.btservices", - ], - min_sdk_version: "30", } cc_library_static { @@ -50,7 +39,6 @@ cc_library_static { include_dirs: ["external/protobuf/src"], }, srcs: [ - "bluetooth/bluetoothKeystore/keystore.proto", "bluetooth/metrics/bluetooth.proto", ], apex_available: [ diff --git a/system/gd/rust/linux/client/src/dbus_iface.rs b/system/gd/rust/linux/client/src/dbus_iface.rs index 5b87b9e01c..98e2e0cc5d 100644 --- a/system/gd/rust/linux/client/src/dbus_iface.rs +++ b/system/gd/rust/linux/client/src/dbus_iface.rs @@ -731,7 +731,7 @@ impl IBluetooth for BluetoothDBus { dbus_generated!() } - fn init(&mut self, init_flags: Vec<String>) -> bool { + fn init(&mut self, _init_flags: Vec<String>) -> bool { // Not implemented by server true } diff --git a/system/gd/rust/linux/service/src/iface_bluetooth.rs b/system/gd/rust/linux/service/src/iface_bluetooth.rs index e006675743..ea651d5966 100644 --- a/system/gd/rust/linux/service/src/iface_bluetooth.rs +++ b/system/gd/rust/linux/service/src/iface_bluetooth.rs @@ -441,7 +441,7 @@ impl IBluetooth for IBluetoothDBus { } // Not exposed over D-Bus. The stack is automatically initialized when the daemon starts. - fn init(&mut self, init_flags: Vec<String>) -> bool { + fn init(&mut self, _init_flags: Vec<String>) -> bool { dbus_generated!() } diff --git a/system/gd/rust/linux/service/src/main.rs b/system/gd/rust/linux/service/src/main.rs index 0f00105a32..1f9a5864c1 100644 --- a/system/gd/rust/linux/service/src/main.rs +++ b/system/gd/rust/linux/service/src/main.rs @@ -431,7 +431,7 @@ fn main() -> Result<(), Box<dyn Error>> { lazy_static! { /// Data needed for signal handling. - static ref SIG_DATA: Mutex<Option<(Sender<Message>, Arc<(SigData)>)>> = Mutex::new(None); + static ref SIG_DATA: Mutex<Option<(Sender<Message>, Arc<SigData>)>> = Mutex::new(None); } extern "C" fn handle_sigterm(_signum: i32) { diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs index a30f07c357..a62ec4ca54 100644 --- a/system/gd/rust/linux/stack/src/bluetooth.rs +++ b/system/gd/rust/linux/stack/src/bluetooth.rs @@ -509,7 +509,7 @@ pub struct Bluetooth { discoverable_timeout: Option<JoinHandle<()>>, /// Used to notify signal handler that we have turned off the stack. - sig_notifier: Arc<(SigData)>, + sig_notifier: Arc<SigData>, } impl Bluetooth { @@ -518,7 +518,7 @@ impl Bluetooth { adapter_index: i32, hci_index: i32, tx: Sender<Message>, - sig_notifier: Arc<(SigData)>, + sig_notifier: Arc<SigData>, intf: Arc<Mutex<BluetoothInterface>>, bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>, bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>, diff --git a/system/gd/rust/linux/stack/src/bluetooth_media.rs b/system/gd/rust/linux/stack/src/bluetooth_media.rs index f26cc91006..d05f02738b 100644 --- a/system/gd/rust/linux/stack/src/bluetooth_media.rs +++ b/system/gd/rust/linux/stack/src/bluetooth_media.rs @@ -1095,6 +1095,15 @@ impl BluetoothMedia { let sleep_duration = (first_conn_ts + total_duration).saturating_duration_since(now_ts); sleep(sleep_duration).await; + Self::async_disconnect(fallback_tasks, device_states, txl, addr).await; + } + + async fn async_disconnect( + fallback_tasks: &Arc<Mutex<HashMap<RawAddress, Option<(JoinHandle<()>, Instant)>>>>, + device_states: &Arc<Mutex<HashMap<RawAddress, DeviceConnectionStates>>>, + txl: &Sender<Message>, + addr: &RawAddress, + ) { device_states.lock().unwrap().insert(*addr, DeviceConnectionStates::Disconnecting); fallback_tasks.lock().unwrap().insert(*addr, None); @@ -1119,6 +1128,16 @@ impl BluetoothMedia { let _ = txl.send(Message::Media(MediaActions::ForceEnterConnected(addr.to_string()))).await; } + fn is_bonded(&self, addr: &RawAddress) -> bool { + match &self.adapter { + Some(adapter) => { + BtBondState::Bonded + == adapter.lock().unwrap().get_bond_state_by_addr(&addr.to_string()) + } + _ => false, + } + } + fn notify_media_capability_updated(&mut self, addr: RawAddress) { let mut guard = self.fallback_tasks.lock().unwrap(); let mut states = self.device_states.lock().unwrap(); @@ -1135,8 +1154,22 @@ impl BluetoothMedia { guard.insert(addr, None); } else { // The device is already added or is disconnecting. - // Ignore unless all profiles are cleared. + // Ignore unless all profiles are cleared, where we need to do some clean up. if !is_profile_cleared { + // Unbonded device is special, we need to reject the connection from them. + if !self.is_bonded(&addr) { + let tasks = self.fallback_tasks.clone(); + let states = self.device_states.clone(); + let txl = self.tx.clone(); + let task = topstack::get_runtime().spawn(async move { + warn!( + "[{}]: Rejecting an unbonded device's attempt to connect media", + DisplayAddress(&addr) + ); + BluetoothMedia::async_disconnect(&tasks, &states, &txl, &addr).await; + }); + guard.insert(addr, Some((task, first_conn_ts))); + } return; } } @@ -1222,39 +1255,18 @@ impl BluetoothMedia { } DeviceConnectionStates::FullyConnected => { // Rejecting the unbonded connection after we finished our profile - // reconnectinglogic to avoid a collision. - if let Some(adapter) = &self.adapter { - if BtBondState::Bonded - != adapter.lock().unwrap().get_bond_state_by_addr(&addr.to_string()) - { - warn!( - "[{}]: Rejecting a unbonded device's attempt to connect to media profiles", - DisplayAddress(&addr)); - let fallback_tasks = self.fallback_tasks.clone(); - let device_states = self.device_states.clone(); - let txl = self.tx.clone(); - let task = topstack::get_runtime().spawn(async move { - { - device_states - .lock() - .unwrap() - .insert(addr, DeviceConnectionStates::Disconnecting); - fallback_tasks.lock().unwrap().insert(addr, None); - } - - debug!( - "[{}]: Device connection state: {:?}.", - DisplayAddress(&addr), - DeviceConnectionStates::Disconnecting - ); + // reconnecting logic to avoid a collision. + if !self.is_bonded(&addr) { + warn!( + "[{}]: Rejecting a unbonded device's attempt to connect to media profiles", + DisplayAddress(&addr) + ); - let _ = txl - .send(Message::Media(MediaActions::Disconnect(addr.to_string()))) - .await; - }); - guard.insert(addr, Some((task, first_conn_ts))); - return; - } + let task = topstack::get_runtime().spawn(async move { + BluetoothMedia::async_disconnect(&tasks, &device_states, &txl, &addr).await; + }); + guard.insert(addr, Some((task, ts))); + return; } let cur_a2dp_caps = self.a2dp_caps.get(&addr); diff --git a/system/gd/rust/topshim/facade/Android.bp b/system/gd/rust/topshim/facade/Android.bp index b18b4eb9c7..37d71e7cc2 100644 --- a/system/gd/rust/topshim/facade/Android.bp +++ b/system/gd/rust/topshim/facade/Android.bp @@ -52,7 +52,6 @@ rust_defaults { "libbt-bta-core", "libbt-common", "libbt-hci", - "libbt-protos-lite", "libbt-sbc-decoder", "libbt-sbc-encoder", "libbt-stack", diff --git a/system/hci/Android.bp b/system/hci/Android.bp index 549e3e14d6..3212482c83 100644 --- a/system/hci/Android.bp +++ b/system/hci/Android.bp @@ -10,7 +10,7 @@ package { // HCI static library for target cc_library_static { name: "libbt-hci", - defaults: ["fluoride_basic_defaults"], + defaults: ["fluoride_defaults"], srcs: [ "src/buffer_allocator.cc", "src/packet_fragmenter.cc", @@ -45,7 +45,7 @@ cc_test { test_suites: ["device-tests"], defaults: [ "bluetooth_gtest_x86_asan_workaround", - "fluoride_basic_defaults", + "fluoride_defaults", "fluoride_test_defaults", "mts_defaults", ], diff --git a/system/main/Android.bp b/system/main/Android.bp index 3de504e9cb..123d749bc0 100644 --- a/system/main/Android.bp +++ b/system/main/Android.bp @@ -20,7 +20,7 @@ filegroup { cc_library_static { name: "libbte", - defaults: ["fluoride_basic_defaults"], + defaults: ["fluoride_defaults"], srcs: [ ":LibBluetoothShimSources", ":LibBluetoothSources", @@ -66,7 +66,7 @@ cc_library { "//packages/modules/Bluetooth:__subpackages__", "//vendor:__subpackages__", ], - defaults: ["fluoride_basic_defaults"], + defaults: ["fluoride_defaults"], header_libs: ["libbluetooth_headers"], export_header_lib_headers: ["libbluetooth_headers"], include_dirs: [ @@ -146,7 +146,6 @@ cc_library_static { "-DBUILDCFG", ], shared_libs: [ - "libflatbuffers-cpp", ], whole_static_libs: [ "libbluetooth_gd", // Gabeldorsche @@ -206,7 +205,6 @@ cc_test { static_libs: [ "libbluetooth-dumpsys", "libbt-common", - "libbt-protos-lite", "libbtdevice", "libchrome", "libevent", diff --git a/system/osi/Android.bp b/system/osi/Android.bp index da4f9cf2e1..f5c6fc8e68 100644 --- a/system/osi/Android.bp +++ b/system/osi/Android.bp @@ -65,7 +65,7 @@ cc_library_static { "include_internal", ], defaults: [ - "fluoride_basic_defaults", + "fluoride_defaults", "fluoride_osi_defaults", ], // TODO(mcchou): Remove socket_utils sources after platform specific @@ -160,7 +160,6 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libc++fs", "libchrome", "libevent", diff --git a/system/osi/test/fuzzers/alarm/Android.bp b/system/osi/test/fuzzers/alarm/Android.bp index 4bcef92af9..4e09043cce 100644 --- a/system/osi/test/fuzzers/alarm/Android.bp +++ b/system/osi/test/fuzzers/alarm/Android.bp @@ -23,7 +23,6 @@ cc_fuzz { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libchrome", "libgmock", "libosi", diff --git a/system/rust/src/gatt/arbiter.rs b/system/rust/src/gatt/arbiter.rs index 52a0aa7207..66841bd977 100644 --- a/system/rust/src/gatt/arbiter.rs +++ b/system/rust/src/gatt/arbiter.rs @@ -52,6 +52,11 @@ pub fn with_arbiter<T>(f: impl FnOnce(&mut IsolationManager) -> T) -> T { f(ARBITER.read().unwrap().as_ref().expect("Rust stack is not started").lock().as_mut().unwrap()) } +/// Check if the Arbiter is initialized. +pub fn has_arbiter() -> bool { + ARBITER.read().unwrap().is_some() +} + /// Test to see if a buffer contains a valid ATT packet with an opcode we /// are interested in intercepting (those intended for servers that are isolated) fn try_parse_att_server_packet( @@ -89,6 +94,13 @@ fn on_le_connect(tcb_idx: u8, advertiser: u8) { } fn on_le_disconnect(tcb_idx: u8) { + // Disconnection events may be received after a FactoryReset + // is initiated for Bluetooth and the rust arbiter is taken + // down. + if !has_arbiter() { + return; + } + let tcb_idx = TransportIndex(tcb_idx); let was_isolated = with_arbiter(|arbiter| arbiter.is_connection_isolated(tcb_idx)); if was_isolated { diff --git a/system/stack/Android.bp b/system/stack/Android.bp index 7a58ff5aca..894ce03266 100644 --- a/system/stack/Android.bp +++ b/system/stack/Android.bp @@ -32,7 +32,7 @@ cc_test_library { // Bluetooth stack static library for target cc_library_static { name: "libbt-stack", - defaults: ["fluoride_basic_defaults"], + defaults: ["fluoride_defaults"], local_include_dirs: [ "avct", "avdt", @@ -125,10 +125,10 @@ cc_library_static { "bnep/bnep_api.cc", "bnep/bnep_main.cc", "bnep/bnep_utils.cc", - "btm/hfp_msbc_decoder.cc", - "btm/hfp_msbc_encoder.cc", "btm/hfp_lc3_decoder.cc", "btm/hfp_lc3_encoder.cc", + "btm/hfp_msbc_decoder.cc", + "btm/hfp_msbc_encoder.cc", "hid/hidd_api.cc", "hid/hidd_conn.cc", "hid/hidh_api.cc", @@ -169,7 +169,7 @@ filegroup { cc_library_static { name: "libbt-stack-core", - defaults: ["fluoride_basic_defaults"], + defaults: ["fluoride_defaults"], local_include_dirs: [ "avct", "avdt", @@ -660,7 +660,6 @@ cc_test { "libbt-bta-core", "libbt-common", "libbt-hci", - "libbt-protos-lite", "libbt-sbc-decoder", "libbt-sbc-encoder", "libbt-stack", @@ -739,10 +738,8 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libchrome", "libevent", - "libflatbuffers-cpp", "libgmock", "liblog", "libosi", @@ -818,7 +815,6 @@ cc_test { static_libs: [ "libchrome", "libevent", - "libflatbuffers-cpp", "libgmock", "liblog", "libosi", @@ -932,7 +928,6 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libchrome", "libevent", "libgmock", @@ -997,7 +992,6 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libchrome", "libevent", "liblog", @@ -1104,7 +1098,6 @@ cc_test { static_libs: [ "libFraunhoferAAC", "libbt-common", - "libbt-protos-lite", "libbt-sbc-decoder", "libbt-sbc-encoder", "libchrome", @@ -1156,7 +1149,6 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libchrome", "liblog", "libosi", @@ -1212,7 +1204,6 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libchrome", "libevent", "libgmock", @@ -1319,7 +1310,6 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libchrome", "libevent", "libgmock", @@ -1417,28 +1407,27 @@ cc_test { "btm/btm_sco_hci.cc", "btm/btm_sco_hfp_hal.cc", "btm/btm_sec.cc", - "btm/hfp_msbc_decoder.cc", - "btm/hfp_msbc_encoder.cc", "btm/hfp_lc3_decoder.cc", "btm/hfp_lc3_encoder.cc", + "btm/hfp_msbc_decoder.cc", + "btm/hfp_msbc_encoder.cc", "metrics/stack_metrics_logging.cc", + "test/btm/btm_scn_test.cc", "test/btm/peer_packet_types_test.cc", "test/btm/sco_hci_test.cc", + "test/btm/sco_pkt_status_test.cc", "test/btm/stack_btm_regression_tests.cc", "test/btm/stack_btm_test.cc", - "test/btm/sco_pkt_status_test.cc", "test/common/mock_eatt.cc", "test/stack_include_test.cc", ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libbt-sbc-decoder", "libbt-sbc-encoder", "libbtdevice", "libchrome", "libevent", - "libflatbuffers-cpp", "libgmock", "liblc3", "liblog", @@ -1486,7 +1475,6 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libbtdevice", "libbte", "libchrome", @@ -1542,7 +1530,6 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libbtdevice", "libbte", "libchrome", @@ -1614,11 +1601,9 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libbtdevice", "libchrome", "libevent", - "libflatbuffers-cpp", "libgmock", "liblog", "libosi", @@ -1696,11 +1681,9 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libbtdevice", "libchrome", "libevent", - "libflatbuffers-cpp", "libgmock", "liblog", "libosi", @@ -1778,11 +1761,9 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libbtdevice", "libchrome", "libevent", - "libflatbuffers-cpp", "libgmock", "liblog", "libosi", @@ -1864,11 +1845,9 @@ cc_test { ], static_libs: [ "libbt-common", - "libbt-protos-lite", "libbtdevice", "libchrome", "libevent", - "libflatbuffers-cpp", "libgmock", "liblog", "libosi", diff --git a/system/stack/btm/btm_int_types.h b/system/stack/btm/btm_int_types.h index 9ad5388ac6..ced48d04e3 100644 --- a/system/stack/btm/btm_int_types.h +++ b/system/stack/btm/btm_int_types.h @@ -18,6 +18,8 @@ #ifndef BTM_INT_TYPES_H #define BTM_INT_TYPES_H +#include <gtest/gtest_prod.h> + #include <cstdint> #include <memory> #include <string> @@ -396,6 +398,14 @@ typedef struct tBTM_CB { friend bool BTM_FreeSCN(uint8_t scn); uint8_t btm_scn[BTM_MAX_SCN_]; uint8_t btm_available_index; + + // give access to private method for test: + friend class BtmAllocateSCNTest; + FRIEND_TEST(BtmAllocateSCNTest, can_allocate_all_scns); + FRIEND_TEST(BtmAllocateSCNTest, only_last_scn_available); + FRIEND_TEST(BtmAllocateSCNTest, scn_available_after_available_index); + FRIEND_TEST(BtmAllocateSCNTest, scn_available_before_available_index); + FRIEND_TEST(BtmAllocateSCNTest, no_scn_available); } tBTM_CB; /* security action for L2CAP COC channels */ diff --git a/system/stack/btm/btm_scn.cc b/system/stack/btm/btm_scn.cc index feec0f5fe7..8e87ccc730 100644 --- a/system/stack/btm/btm_scn.cc +++ b/system/stack/btm/btm_scn.cc @@ -34,8 +34,11 @@ extern tBTM_CB btm_cb; uint8_t BTM_AllocateSCN(void) { BTM_TRACE_DEBUG("BTM_AllocateSCN"); - // stack reserves scn 1 for HFP, HSP we still do the correct way - for (uint8_t x = btm_cb.btm_available_index; x < PORT_MAX_RFC_PORTS; x++) { + // stack reserves scn 1 for HFP, HSP we still do the correct way. + // SCN can be allocated in the range of [1, PORT_MAX_RFC_PORTS). Since (x + 1) + // is returned, we iterate to less than PORT_MAX_RFC_PORTS - 1. + for (uint8_t x = btm_cb.btm_available_index; x < PORT_MAX_RFC_PORTS - 1; + x++) { if (!btm_cb.btm_scn[x]) { btm_cb.btm_scn[x] = true; btm_cb.btm_available_index = (x + 1); @@ -43,10 +46,10 @@ uint8_t BTM_AllocateSCN(void) { } } - // In order to avoid OOB, btm_available_index must be less than or equal to - // PORT_MAX_RFC_PORTS + // In order to avoid OOB, btm_available_index must be less than + // PORT_MAX_RFC_PORTS. btm_cb.btm_available_index = - std::min(btm_cb.btm_available_index, (uint8_t)PORT_MAX_RFC_PORTS); + std::min(btm_cb.btm_available_index, (uint8_t)(PORT_MAX_RFC_PORTS - 1)); // If there's no empty SCN from _last_index to BTM_MAX_SCN. for (uint8_t y = 1; y < btm_cb.btm_available_index; y++) { diff --git a/system/stack/btm/btm_scn.h b/system/stack/btm/btm_scn.h index fe9dcb7ad6..733173297b 100644 --- a/system/stack/btm/btm_scn.h +++ b/system/stack/btm/btm_scn.h @@ -18,6 +18,6 @@ #include <cstdint> +uint8_t BTM_AllocateSCN(void); bool BTM_FreeSCN(uint8_t scn); bool BTM_TryAllocateSCN(uint8_t scn); -bool BTM_TryAllocateSCN(uint8_t scn); diff --git a/system/stack/test/btm/btm_scn_test.cc b/system/stack/test/btm/btm_scn_test.cc new file mode 100644 index 0000000000..38294e312d --- /dev/null +++ b/system/stack/test/btm/btm_scn_test.cc @@ -0,0 +1,91 @@ +/* + * + * Copyright 2023 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. + * + */ + +#include "stack/btm/btm_scn.h" + +#include <gtest/gtest.h> + +#include "stack/btm/btm_int_types.h" // tBTM_CB +#include "stack/include/rfcdefs.h" // PORT_MAX_RFC_PORTS + +extern tBTM_CB btm_cb; + +using testing::Test; + +class BtmAllocateSCNTest : public Test { + public: + protected: + void SetUp() override { + btm_cb.btm_available_index = 1; + for (int i = 0; i < PORT_MAX_RFC_PORTS; i++) { + btm_cb.btm_scn[i] = false; + } + } + + void TearDown() override {} +}; + +TEST_F(BtmAllocateSCNTest, scn_available_after_available_index) { + btm_cb.btm_available_index = 5; + uint8_t occupied_idx[] = {1, 2, 3, 4, 5, 6, 7}; + for (uint8_t idx : occupied_idx) { + btm_cb.btm_scn[idx] = true; + } + + uint8_t scn = BTM_AllocateSCN(); + ASSERT_EQ(scn, 9); // All indexes up to 7 are occupied; hence index 8 i.e. + // scn 9 should return +} + +TEST_F(BtmAllocateSCNTest, scn_available_before_available_index) { + btm_cb.btm_available_index = 28; + uint8_t occupied_idx[] = {26, 27, 28, 29}; + for (uint8_t idx : occupied_idx) { + btm_cb.btm_scn[idx] = true; + } + + uint8_t scn = BTM_AllocateSCN(); + ASSERT_EQ(scn, 2); // All SCN from available to 30 are occupied; hence cycle + // to beginning. +} + +TEST_F(BtmAllocateSCNTest, can_allocate_all_scns) { + for (uint8_t scn = 2; scn < PORT_MAX_RFC_PORTS; scn++) { + EXPECT_EQ(BTM_AllocateSCN(), scn); + } +} + +TEST_F(BtmAllocateSCNTest, only_last_scn_available) { + // Fill all relevants SCN except the last + for (uint8_t scn = 2; scn < PORT_MAX_RFC_PORTS - 1; scn++) { + btm_cb.btm_scn[scn - 1] = true; + } + + EXPECT_EQ(BTM_AllocateSCN(), PORT_MAX_RFC_PORTS - 1); +} + +TEST_F(BtmAllocateSCNTest, no_scn_available) { + btm_cb.btm_available_index = 2; + for (int i = 1; i < PORT_MAX_RFC_PORTS - 1; + i++) { // Fill all relevants SCN indexes (1 to 29) + btm_cb.btm_scn[i] = true; + } + + uint8_t scn = BTM_AllocateSCN(); + EXPECT_EQ(scn, 0) << "scn = " << scn << "and not 0"; +}
\ No newline at end of file diff --git a/system/stack/test/fuzzers/Android.bp b/system/stack/test/fuzzers/Android.bp index 822bc50312..d187b961ed 100644 --- a/system/stack/test/fuzzers/Android.bp +++ b/system/stack/test/fuzzers/Android.bp @@ -29,7 +29,6 @@ cc_defaults { "libbt-bta-core", "libbt-common", "libbt-hci", - "libbt-protos-lite", "libbt-sbc-decoder", "libbt-sbc-encoder", "libbt-stack", diff --git a/system/test/headless/Android.bp b/system/test/headless/Android.bp index aad71a9995..e1f667cc34 100644 --- a/system/test/headless/Android.bp +++ b/system/test/headless/Android.bp @@ -92,7 +92,6 @@ cc_binary { "libbt-bta-core", "libbt-common", "libbt-hci", - "libbt-protos-lite", "libbt-sbc-decoder", "libbt-sbc-encoder", "libbt-stack", diff --git a/system/test/mock/mock_btif_co_bta_av_co.cc b/system/test/mock/mock_btif_co_bta_av_co.cc index 15612db986..0241237208 100644 --- a/system/test/mock/mock_btif_co_bta_av_co.cc +++ b/system/test/mock/mock_btif_co_bta_av_co.cc @@ -49,7 +49,6 @@ struct bta_av_co_audio_source_data_path bta_av_co_audio_source_data_path; struct bta_av_co_audio_start bta_av_co_audio_start; struct bta_av_co_audio_stop bta_av_co_audio_stop; struct bta_av_co_audio_update_mtu bta_av_co_audio_update_mtu; -struct bta_av_co_get_decoder_interface bta_av_co_get_decoder_interface; struct bta_av_co_get_encoder_effective_frame_size bta_av_co_get_encoder_effective_frame_size; struct bta_av_co_get_encoder_interface bta_av_co_get_encoder_interface; @@ -76,8 +75,6 @@ namespace btif_co_bta_av_co { tA2DP_STATUS bta_av_co_audio_getconfig::return_value = 0; bool bta_av_co_audio_init::return_value = false; BT_HDR* bta_av_co_audio_source_data_path::return_value = nullptr; -const tA2DP_DECODER_INTERFACE* bta_av_co_get_decoder_interface::return_value = - nullptr; int bta_av_co_get_encoder_effective_frame_size::return_value = 0; const tA2DP_ENCODER_INTERFACE* bta_av_co_get_encoder_interface::return_value = nullptr; @@ -180,10 +177,6 @@ void bta_av_co_audio_update_mtu(tBTA_AV_HNDL bta_av_handle, test::mock::btif_co_bta_av_co::bta_av_co_audio_update_mtu(bta_av_handle, peer_address, mtu); } -const tA2DP_DECODER_INTERFACE* bta_av_co_get_decoder_interface(void) { - inc_func_call_count(__func__); - return test::mock::btif_co_bta_av_co::bta_av_co_get_decoder_interface(); -} int bta_av_co_get_encoder_effective_frame_size() { inc_func_call_count(__func__); return test::mock::btif_co_bta_av_co:: diff --git a/system/test/mock/mock_btif_co_bta_av_co.h b/system/test/mock/mock_btif_co_bta_av_co.h index 9f977ce53f..c817f8359c 100644 --- a/system/test/mock/mock_btif_co_bta_av_co.h +++ b/system/test/mock/mock_btif_co_bta_av_co.h @@ -260,17 +260,6 @@ struct bta_av_co_audio_update_mtu { }; extern struct bta_av_co_audio_update_mtu bta_av_co_audio_update_mtu; -// Name: bta_av_co_get_decoder_interface -// Params: void -// Return: const tA2DP_DECODER_INTERFACE* -struct bta_av_co_get_decoder_interface { - static const tA2DP_DECODER_INTERFACE* return_value; - std::function<const tA2DP_DECODER_INTERFACE*(void)> body{ - [](void) { return return_value; }}; - const tA2DP_DECODER_INTERFACE* operator()(void) { return body(); }; -}; -extern struct bta_av_co_get_decoder_interface bta_av_co_get_decoder_interface; - // Name: bta_av_co_get_encoder_effective_frame_size // Params: // Return: int diff --git a/tools/rootcanal/model/controller/link_layer_controller.cc b/tools/rootcanal/model/controller/link_layer_controller.cc index 57605cf497..adafc72b99 100644 --- a/tools/rootcanal/model/controller/link_layer_controller.cc +++ b/tools/rootcanal/model/controller/link_layer_controller.cc @@ -682,7 +682,7 @@ ErrorCode LinkLayerController::LeAddDeviceToResolvingList( for (auto const& entry : le_resolving_list_) { if ((entry.peer_identity_address_type == peer_identity_address_type && entry.peer_identity_address == peer_identity_address) || - entry.peer_irk == peer_irk) { + (entry.peer_irk == peer_irk && !irk_is_zero(peer_irk))) { INFO(id_, "device is already present in the resolving list"); return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; } @@ -2837,6 +2837,10 @@ Address LinkLayerController::generate_rpa( return rpa; } +bool LinkLayerController::irk_is_zero(std::array<uint8_t, LinkLayerController::kIrkSize> irk) { + return std::all_of(irk.begin(), irk.end(), [](uint8_t b) { return b == 0; }); +} + // Handle legacy advertising PDUs while in the Scanning state. void LinkLayerController::ScanIncomingLeLegacyAdvertisingPdu( model::packets::LeLegacyAdvertisingPduView& pdu, uint8_t rssi) { diff --git a/tools/rootcanal/model/controller/link_layer_controller.h b/tools/rootcanal/model/controller/link_layer_controller.h index ebbe4d8565..3e036faff6 100644 --- a/tools/rootcanal/model/controller/link_layer_controller.h +++ b/tools/rootcanal/model/controller/link_layer_controller.h @@ -63,6 +63,9 @@ class LinkLayerController { static Address generate_rpa( std::array<uint8_t, LinkLayerController::kIrkSize> irk); + // Return true if the input IRK is all 0s. + static bool irk_is_zero(std::array<uint8_t, LinkLayerController::kIrkSize> irk); + LinkLayerController(const Address& address, const ControllerProperties& properties, int id = 0); ~LinkLayerController(); diff --git a/tools/rootcanal/test/controller/le/le_add_device_to_resolving_list_test.cc b/tools/rootcanal/test/controller/le/le_add_device_to_resolving_list_test.cc index 427861e0e9..b2a44d4812 100644 --- a/tools/rootcanal/test/controller/le/le_add_device_to_resolving_list_test.cc +++ b/tools/rootcanal/test/controller/le/le_add_device_to_resolving_list_test.cc @@ -130,4 +130,16 @@ TEST_F(LeAddDeviceToResolvingListTest, PeerIrkDuplicate) { ErrorCode::INVALID_HCI_COMMAND_PARAMETERS); } +TEST_F(LeAddDeviceToResolvingListTest, EmptyPeerIrkDuplicate) { + ASSERT_EQ(controller_.LeAddDeviceToResolvingList( + PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address{1}, + std::array<uint8_t, 16>{0}, std::array<uint8_t, 16>{1}), + ErrorCode::SUCCESS); + + ASSERT_EQ(controller_.LeAddDeviceToResolvingList( + PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS, Address{1}, + std::array<uint8_t, 16>{0}, std::array<uint8_t, 16>{1}), + ErrorCode::SUCCESS); +} + } // namespace rootcanal |