summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp2
-rw-r--r--android/app/Android.bp13
-rw-r--r--android/app/AndroidManifest.xml11
-rw-r--r--android/app/jni/com_android_bluetooth_btservice_ActivityAttribution.cpp131
-rw-r--r--android/app/jni/com_android_bluetooth_gatt.cpp8
-rw-r--r--android/app/proto/keystore.proto (renamed from system/gd/proto/bluetooth/bluetoothKeystore/keystore.proto)3
-rw-r--r--android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java1
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java23
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java2
-rw-r--r--android/app/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java34
-rw-r--r--android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java70
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterService.java127
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterState.java12
-rw-r--r--android/app/src/com/android/bluetooth/btservice/BondStateMachine.java10
-rw-r--r--android/app/src/com/android/bluetooth/btservice/Config.java51
-rw-r--r--android/app/src/com/android/bluetooth/btservice/ProfileService.java11
-rw-r--r--android/app/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionNativeInterface.java42
-rw-r--r--android/app/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionService.java103
-rw-r--r--android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java74
-rw-r--r--android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java43
-rw-r--r--android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java4
-rw-r--r--android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java88
-rw-r--r--android/app/src/com/android/bluetooth/gatt/AdvertiseManagerNativeInterface.java178
-rw-r--r--android/app/src/com/android/bluetooth/gatt/GattService.java52
-rw-r--r--android/app/src/com/android/bluetooth/le_audio/LeAudioService.java32
-rw-r--r--android/app/src/com/android/bluetooth/le_audio/LeAudioStateMachine.java14
-rw-r--r--android/app/tests/unit/AndroidTest.xml4
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/TestUtils.java58
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java69
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java20
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java54
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java3
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java101
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/ConfigTest.java51
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java60
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionServiceTest.java15
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreServiceTest.java29
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/AppScanStatsTest.java25
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java24
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java54
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/gatt/ScanManagerTest.java21
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java3
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java74
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java10
-rw-r--r--android/pandora/test/AndroidTest.xml4
-rw-r--r--android/pandora/test/asha_test.py6
-rw-r--r--android/pandora/test/config.yml4
-rw-r--r--floss/hcidoc/src/groups/informational.rs297
-rw-r--r--framework/java/android/bluetooth/BluetoothGattServer.java6
-rw-r--r--service/Android.bp5
-rw-r--r--service/src/com/android/server/bluetooth/BluetoothManagerService.java23
-rw-r--r--system/audio_hal_interface/fuzzer/Android.bp1
-rw-r--r--system/binder/android/bluetooth/IBluetoothGatt.aidl7
-rw-r--r--system/bta/Android.bp35
-rw-r--r--system/bta/dm/bta_dm_act.cc57
-rw-r--r--system/bta/test/bta_dm_test.cc19
-rw-r--r--system/bta/test/bta_sdp_test.cc8
-rw-r--r--system/btcore/Android.bp4
-rw-r--r--system/btif/Android.bp30
-rw-r--r--system/btif/co/bta_av_co.cc21
-rw-r--r--system/btif/include/btif_av_co.h6
-rw-r--r--system/btif/src/btif_a2dp_sink.cc3
-rw-r--r--system/btif/src/btif_av.cc6
-rw-r--r--system/btif/src/btif_avrcp_audio_track.cc4
-rw-r--r--system/btif/src/btif_dm.cc5
-rw-r--r--system/build/Android.bp20
-rw-r--r--system/common/Android.bp16
-rw-r--r--system/device/Android.bp6
-rw-r--r--system/device/fuzzer/Android.bp1
-rw-r--r--system/doc/btsnoop_net.md16
-rw-r--r--system/doc/log_tags.md57
-rw-r--r--system/doc/network_ports.md8
-rw-r--r--system/doc/properties.md20
-rw-r--r--system/doc/pts_guide.md43
-rw-r--r--system/doc/supported_features.md19
-rw-r--r--system/gd/Android.bp6
-rw-r--r--system/gd/btaa/activity_attribution.h12
-rw-r--r--system/gd/btaa/android/activity_attribution.cc9
-rw-r--r--system/gd/btaa/host/activity_attribution.cc2
-rw-r--r--system/gd/btaa/linux/activity_attribution.cc4
-rw-r--r--system/gd/dumpsys/bundler/Android.bp1
-rw-r--r--system/gd/proto/Android.bp16
-rw-r--r--system/gd/rust/linux/client/src/dbus_iface.rs2
-rw-r--r--system/gd/rust/linux/service/src/iface_bluetooth.rs2
-rw-r--r--system/gd/rust/linux/service/src/main.rs2
-rw-r--r--system/gd/rust/linux/stack/src/bluetooth.rs4
-rw-r--r--system/gd/rust/linux/stack/src/bluetooth_media.rs78
-rw-r--r--system/gd/rust/topshim/Android.bp2
-rw-r--r--system/gd/rust/topshim/facade/Android.bp1
-rw-r--r--system/hci/Android.bp7
-rw-r--r--system/include/hardware/bt_activity_attribution.h41
-rw-r--r--system/main/Android.bp11
-rw-r--r--system/main/shim/activity_attribution.cc47
-rw-r--r--system/main/shim/activity_attribution.h2
-rw-r--r--system/main/shim/stack.cc3
-rw-r--r--system/main/test/main_shim_test.cc2
-rw-r--r--system/osi/Android.bp4
-rw-r--r--system/osi/test/fuzzers/alarm/Android.bp1
-rw-r--r--system/profile/avrcp/Android.bp1
-rw-r--r--system/rust/src/gatt/arbiter.rs12
-rw-r--r--system/stack/Android.bp54
-rw-r--r--system/stack/btm/btm_int_types.h10
-rw-r--r--system/stack/btm/btm_scn.cc13
-rw-r--r--system/stack/btm/btm_scn.h2
-rw-r--r--system/stack/l2cap/l2c_csm.cc10
-rw-r--r--system/stack/test/btm/btm_scn_test.cc91
-rw-r--r--system/stack/test/fuzzers/Android.bp1
-rw-r--r--system/test/headless/Android.bp1
-rw-r--r--system/test/mock/mock_bta_dm_act.cc5
-rw-r--r--system/test/mock/mock_bta_dm_act.h10
-rw-r--r--system/test/mock/mock_btif_co_bta_av_co.cc7
-rw-r--r--system/test/mock/mock_btif_co_bta_av_co.h11
-rw-r--r--system/test/mock/mock_main_shim_activity_attribution.cc3
-rwxr-xr-xsystem/test/run_benchmarks.sh129
-rwxr-xr-xsystem/test/run_host_unit_tests.py212
-rwxr-xr-xsystem/test/run_unit_tests.sh161
-rw-r--r--system/test/suite/Android.bp3
-rw-r--r--system/tools/Android.mk.disabled1
-rw-r--r--system/tools/bdtool/Android.mk.disabled48
-rw-r--r--system/tools/bdtool/adapter.c276
-rw-r--r--system/tools/bdtool/bdtool.c362
-rw-r--r--system/tools/hci/Android.mk.disabled33
-rw-r--r--system/tools/hci/main.c216
-rwxr-xr-xsystem/tools/scripts/change_types.sh85
-rw-r--r--system/vendor_libs/linux/interface/Android.bp1
-rw-r--r--tools/OWNERS1
-rwxr-xr-xtools/bt-api-plumber/bt-api-plumber-9000.sh559
-rw-r--r--tools/rootcanal/Android.bp19
-rw-r--r--tools/rootcanal/CMakeLists.txt6
-rw-r--r--tools/rootcanal/hal/bluetooth_hci.cc2
-rw-r--r--tools/rootcanal/model/controller/dual_mode_controller.cc33
-rw-r--r--tools/rootcanal/model/controller/link_layer_controller.cc56
-rw-r--r--tools/rootcanal/model/controller/link_layer_controller.h8
-rw-r--r--tools/rootcanal/model/devices/hci_device.cc38
-rw-r--r--tools/rootcanal/model/hci/hci_sniffer.cc51
-rw-r--r--tools/rootcanal/model/hci/hci_sniffer.h15
-rw-r--r--tools/rootcanal/model/hci/hci_socket_transport.cc41
-rw-r--r--tools/rootcanal/model/hci/hci_socket_transport.h17
-rw-r--r--tools/rootcanal/model/hci/hci_transport.h24
-rw-r--r--tools/rootcanal/packets/hci_packets.pdl (renamed from tools/rootcanal/packets/hci/hci_packets.pdl)48
-rw-r--r--tools/rootcanal/py/controller.py18
-rw-r--r--tools/rootcanal/rust/CMakeLists.txt2
-rw-r--r--tools/rootcanal/rust/build.rs6
-rw-r--r--tools/rootcanal/rust/src/lmp/procedure/secure_simple_pairing.rs203
-rw-r--r--tools/rootcanal/rust/test/SP/BV-14bis-C.in106
-rw-r--r--tools/rootcanal/rust/test/SP/BV-15bis-C.in118
-rw-r--r--tools/rootcanal/test/LL/CON_/CEN/BV_41_C.py14
-rw-r--r--tools/rootcanal/test/LL/CON_/CEN/BV_43_C.py14
-rw-r--r--tools/rootcanal/test/LL/CON_/PER/BV_40_C.py4
-rw-r--r--tools/rootcanal/test/LL/CON_/PER/BV_42_C.py4
-rw-r--r--tools/rootcanal/test/LL/DDI/ADV/BV_06_C.py4
-rw-r--r--tools/rootcanal/test/LL/DDI/ADV/BV_07_C.py4
-rw-r--r--tools/rootcanal/test/LL/DDI/ADV/BV_09_C.py8
-rw-r--r--tools/rootcanal/test/LL/DDI/ADV/BV_11_C.py4
-rw-r--r--tools/rootcanal/test/LL/DDI/ADV/BV_19_C.py4
-rw-r--r--tools/rootcanal/test/LL/DDI/SCN/BV_19_C.py8
-rw-r--r--tools/rootcanal/test/LL/DDI/SCN/BV_79_C.py8
-rw-r--r--tools/rootcanal/test/controller/le/le_add_device_to_resolving_list_test.cc12
-rw-r--r--tools/rootcanal/test/controller/le/le_scanning_filter_duplicates_test.cc2
-rw-r--r--tools/rootcanal/test/controller/le/le_set_extended_scan_enable_test.cc96
-rw-r--r--tools/rootcanal/test/controller/le/le_set_extended_scan_parameters_test.cc59
-rw-r--r--tools/rootcanal/test/controller/le/test_helpers.h10
164 files changed, 2200 insertions, 4028 deletions
diff --git a/Android.bp b/Android.bp
index 7be2e6ec9e..aef08f38e9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -76,6 +76,8 @@ cc_defaults {
// there are too many unused parameters in all the code.
"-Wno-unused-parameter",
],
+ c_std: "c99",
+ cpp_std: "c++17",
}
// Address Sanitizer is flaky on Android x86_64 binaries but it's not on x86
diff --git a/android/app/Android.bp b/android/app/Android.bp
index 2bf58974cb..239d410074 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: [
@@ -77,7 +77,7 @@ cc_library_shared {
// is required to maintain FIPS compliance.
stl: "libc++_static",
static_libs: [
- "android.hardware.audio.common-V1-ndk",
+ "android.hardware.audio.common-V2-ndk",
"android.hardware.audio.common@5.0",
"android.hardware.bluetooth.audio-V3-ndk",
"android.hardware.bluetooth.audio@2.0",
@@ -100,6 +100,7 @@ cc_library_shared {
"libbluetooth-types",
"libbluetooth_core_rs",
"libbluetooth_core_rs_bridge",
+ "libbluetooth_gd",
"libbt-audio-hal-interface",
"libbt-bta",
"libbt-bta-core",
@@ -118,6 +119,7 @@ cc_library_shared {
"libchrome",
"libcutils",
"libevent",
+ "libflatbuffers-cpp",
"libfmq",
"libg722codec",
"libhidlbase",
@@ -125,6 +127,7 @@ cc_library_shared {
"libmodpb64",
"libopus",
"libosi",
+ "libprotobuf-cpp-lite",
"libudrv-uipc",
"libutils",
],
@@ -148,7 +151,7 @@ cc_library_shared {
cc_library {
name: "libbluetooth-core",
- defaults: ["fluoride_basic_defaults"],
+ defaults: ["fluoride_defaults"],
header_libs: [
"jni_headers",
"libbluetooth_headers",
@@ -199,8 +202,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/android/app/AndroidManifest.xml b/android/app/AndroidManifest.xml
index 929cc0e42b..7a398344c0 100644
--- a/android/app/AndroidManifest.xml
+++ b/android/app/AndroidManifest.xml
@@ -221,17 +221,6 @@
</intent-filter>
</service>
- <!-- Generic Attribute (GATT) Profile Service -->
- <service android:process="@string/process"
- android:name="com.android.bluetooth.gatt.GattService"
- android:enabled="true"
- android:exported="true"
- android:permission="android.permission.ACCESS_BLUETOOTH_SHARE">
- <intent-filter>
- <action android:name="android.bluetooth.IBluetoothGatt"/>
- </intent-filter>
- </service>
-
<!-- Hearing Aid Profile (HAP) client Profile Service -->
<service android:process="@string/process"
android:name="com.android.bluetooth.hap.HapClientService"
diff --git a/android/app/jni/com_android_bluetooth_btservice_ActivityAttribution.cpp b/android/app/jni/com_android_bluetooth_btservice_ActivityAttribution.cpp
index 4e0247dccc..2790b00903 100644
--- a/android/app/jni/com_android_bluetooth_btservice_ActivityAttribution.cpp
+++ b/android/app/jni/com_android_bluetooth_btservice_ActivityAttribution.cpp
@@ -24,138 +24,10 @@
#include "com_android_bluetooth.h"
#include "hardware/bt_activity_attribution.h"
-using bluetooth::activity_attribution::ActivityAttributionCallbacks;
using bluetooth::activity_attribution::ActivityAttributionInterface;
namespace android {
-static jmethodID method_onWakeup;
-static jmethodID method_onActivityLogsReady;
-
static ActivityAttributionInterface* sActivityAttributionInterface = nullptr;
-static std::shared_timed_mutex interface_mutex;
-
-static jobject mCallbacksObj = nullptr;
-static std::shared_timed_mutex callbacks_mutex;
-
-class ActivityAttributionCallbacksImpl : public ActivityAttributionCallbacks {
- public:
- ~ActivityAttributionCallbacksImpl() = default;
-
- void OnWakeup(const Activity activity, const RawAddress& bd_addr) override {
- LOG(INFO) << __func__;
-
- std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
- CallbackEnv sCallbackEnv(__func__);
- if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return;
-
- ScopedLocalRef<jbyteArray> addr(
- sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
- if (!addr.get()) {
- LOG(ERROR)
- << "Failed to allocate jbyteArray for bd_addr of wakeup callback";
- return;
- }
-
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
- (jbyte*)&bd_addr);
- sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWakeup, (jint)activity,
- addr.get());
- }
-
- void OnActivityLogsReady(
- const std::vector<BtaaAggregationEntry> logs) override {
- LOG(INFO) << __func__;
-
- std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
- CallbackEnv sCallbackEnv(__func__);
- if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return;
-
- jsize logs_size = logs.size() * sizeof(BtaaAggregationEntry);
- ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(),
- sCallbackEnv->NewByteArray(logs_size));
- if (!addr.get()) {
- LOG(ERROR) << "Failed to allocate jbyteArray for logs from activity "
- "logging callback";
- return;
- }
-
- sCallbackEnv->SetByteArrayRegion(addr.get(), 0, logs_size,
- (jbyte*)logs.data());
- sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onActivityLogsReady,
- addr.get());
- }
-};
-
-static ActivityAttributionCallbacksImpl sActivityAttributionCallbacks;
-
-static void classInitNative(JNIEnv* env, jclass clazz) {
- method_onWakeup = env->GetMethodID(clazz, "onWakeup", "(I[B)V");
- method_onActivityLogsReady =
- env->GetMethodID(clazz, "onActivityLogsReady", "([B)V");
-
- LOG(INFO) << __func__ << ": succeeds";
-}
-
-static void initNative(JNIEnv* env, jobject object) {
- std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
- std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex);
- const bt_interface_t* btInf = getBluetoothInterface();
- if (btInf == nullptr) {
- LOG(ERROR) << "Bluetooth module is not loaded";
- return;
- }
-
- if (sActivityAttributionInterface != nullptr) {
- LOG(INFO)
- << "Cleaning up ActivityAttribution Interface before initializing...";
- sActivityAttributionInterface->Cleanup();
- sActivityAttributionInterface = nullptr;
- }
-
- if (mCallbacksObj != nullptr) {
- LOG(INFO) << "Cleaning up ActivityAttribution callback object";
- env->DeleteGlobalRef(mCallbacksObj);
- mCallbacksObj = nullptr;
- }
-
- if ((mCallbacksObj = env->NewGlobalRef(object)) == nullptr) {
- LOG(ERROR)
- << "Failed to allocate Global Ref for ActivityAttribution Callbacks";
- return;
- }
-
- sActivityAttributionInterface =
- (ActivityAttributionInterface*)btInf->get_profile_interface(
- BT_ACTIVITY_ATTRIBUTION_ID);
- if (sActivityAttributionInterface == nullptr) {
- LOG(ERROR) << "Failed to get ActivityAttribution Interface";
- return;
- }
-
- sActivityAttributionInterface->RegisterCallbacks(
- &sActivityAttributionCallbacks);
-}
-
-static void cleanupNative(JNIEnv* env, jobject object) {
- std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
- std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex);
-
- const bt_interface_t* btInf = getBluetoothInterface();
- if (btInf == nullptr) {
- LOG(ERROR) << "Bluetooth module is not loaded";
- return;
- }
-
- if (sActivityAttributionInterface != nullptr) {
- sActivityAttributionInterface->Cleanup();
- sActivityAttributionInterface = nullptr;
- }
-
- if (mCallbacksObj != nullptr) {
- env->DeleteGlobalRef(mCallbacksObj);
- mCallbacksObj = nullptr;
- }
-}
static void notifyActivityAttributionInfoNative(JNIEnv* env, jobject object,
jint uid, jstring packageName,
@@ -186,9 +58,6 @@ static void notifyActivityAttributionInfoNative(JNIEnv* env, jobject object,
}
static JNINativeMethod sMethods[] = {
- {"classInitNative", "()V", (void*)classInitNative},
- {"initNative", "()V", (void*)initNative},
- {"cleanupNative", "()V", (void*)cleanupNative},
{"notifyActivityAttributionInfoNative",
"(ILjava/lang/String;Ljava/lang/String;)V",
(void*)notifyActivityAttributionInfoNative},
diff --git a/android/app/jni/com_android_bluetooth_gatt.cpp b/android/app/jni/com_android_bluetooth_gatt.cpp
index 1290aae868..1c329d68b2 100644
--- a/android/app/jni/com_android_bluetooth_gatt.cpp
+++ b/android/app/jni/com_android_bluetooth_gatt.cpp
@@ -2682,7 +2682,7 @@ static void stopDistanceMeasurementNative(JNIEnv* env, jobject object,
* JNI function definitinos
*/
-// JNI functions defined in AdvertiseManager class.
+// JNI functions defined in AdvertiseManagerNativeInterface class.
static JNINativeMethod sAdvertiseMethods[] = {
{"classInitNative", "()V", (void*)advertiseClassInitNative},
{"initializeNative", "()V", (void*)advertiseInitializeNative},
@@ -2691,8 +2691,8 @@ static JNINativeMethod sAdvertiseMethods[] = {
"(Landroid/bluetooth/le/AdvertisingSetParameters;[B[BLandroid/bluetooth/"
"le/PeriodicAdvertisingParameters;[BIIII)V",
(void*)startAdvertisingSetNative},
- {"getOwnAddressNative", "(I)V", (void*)getOwnAddressNative},
{"stopAdvertisingSetNative", "(I)V", (void*)stopAdvertisingSetNative},
+ {"getOwnAddressNative", "(I)V", (void*)getOwnAddressNative},
{"enableAdvertisingSetNative", "(IZII)V",
(void*)enableAdvertisingSetNative},
{"setAdvertisingDataNative", "(I[B)V", (void*)setAdvertisingDataNative},
@@ -2848,8 +2848,8 @@ int register_com_android_bluetooth_gatt(JNIEnv* env) {
env, "com/android/bluetooth/gatt/ScanNativeInterface", sScanMethods,
NELEM(sScanMethods));
register_success &= jniRegisterNativeMethods(
- env, "com/android/bluetooth/gatt/AdvertiseManager", sAdvertiseMethods,
- NELEM(sAdvertiseMethods));
+ env, "com/android/bluetooth/gatt/AdvertiseManagerNativeInterface",
+ sAdvertiseMethods, NELEM(sAdvertiseMethods));
register_success &= jniRegisterNativeMethods(
env, "com/android/bluetooth/gatt/PeriodicScanManager",
sPeriodicScanMethods, NELEM(sPeriodicScanMethods));
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/a2dpsink/A2dpSinkService.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
index e7b0920476..02e8a5ace4 100644
--- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
+++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
@@ -134,6 +134,7 @@ public class A2dpSinkService extends ProfileService {
* Set the device that should be allowed to actively stream
*/
public boolean setActiveDevice(BluetoothDevice device) {
+ Log.i(TAG, "setActiveDevice(device=" + device + ")");
synchronized (mActiveDeviceLock) {
if (mNativeInterface.setActiveDevice(device)) {
mActiveDevice = device;
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
index 25c7f9e7a1..a43594df76 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
@@ -208,8 +208,12 @@ public class AvrcpControllerService extends ProfileService {
*/
@VisibleForTesting
boolean setActiveDevice(BluetoothDevice device) {
+ if (DBG) {
+ Log.d(TAG, "setActiveDevice(device=" + device + ")");
+ }
A2dpSinkService a2dpSinkService = A2dpSinkService.getA2dpSinkService();
if (a2dpSinkService == null) {
+ Log.w(TAG, "setActiveDevice(device=" + device + "): A2DP Sink not available");
return false;
}
@@ -242,6 +246,8 @@ public class AvrcpControllerService extends ProfileService {
return true;
}
}
+
+ Log.w(TAG, "setActiveDevice(device=" + device + "): A2DP Sink request failed");
return false;
}
@@ -333,15 +339,21 @@ public class AvrcpControllerService extends ProfileService {
for (AvrcpControllerStateMachine stateMachine : mDeviceStateMap.values()) {
requestedNode = stateMachine.findNode(parentMediaId);
if (requestedNode != null) {
- Log.d(TAG, "Found a node");
break;
}
}
}
+
+ if (DBG) {
+ Log.d(TAG, "getContents(" + parentMediaId + "): "
+ + (requestedNode == null
+ ? "Failed to find node"
+ : "node=" + requestedNode + ", device=" + requestedNode.getDevice()));
+ }
+
// If we don't find a node in the tree then do not have any way to browse for the contents.
// Return an empty list instead.
if (requestedNode == null) {
- if (DBG) Log.d(TAG, "Didn't find a node");
return new BrowseResult(new ArrayList(0), BrowseResult.ERROR_MEDIA_ID_INVALID);
}
if (parentMediaId.equals(BrowseTree.ROOT) && requestedNode.getChildrenCount() == 0) {
@@ -355,9 +367,8 @@ public class AvrcpControllerService extends ProfileService {
List<MediaItem> contents = requestedNode.getContents();
- if (DBG) Log.d(TAG, "Returning contents");
if (!requestedNode.isCached()) {
- if (DBG) Log.d(TAG, "node is not cached");
+ if (DBG) Log.d(TAG, "getContents(" + parentMediaId + "): node download pending");
refreshContents(requestedNode);
/* Ongoing downloads can have partial results and we want to make sure they get sent
* to the client. If a download gets kicked off as a result of this request, the
@@ -365,6 +376,10 @@ public class AvrcpControllerService extends ProfileService {
*/
return new BrowseResult(contents, BrowseResult.DOWNLOAD_PENDING);
}
+ if (DBG) {
+ Log.d(TAG, "getContents(" + parentMediaId + "): return node, contents="
+ + requestedNode.getContents());
+ }
return new BrowseResult(contents, BrowseResult.SUCCESS);
}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
index 290dc35cb4..9f43d8199f 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
@@ -581,6 +581,8 @@ class AvrcpControllerStateMachine extends StateMachine {
mAddressedPlayer.updateCurrentTrack(track);
if (isActive()) {
BluetoothMediaBrowserService.trackChanged(track);
+ BluetoothMediaBrowserService.notifyChanged(
+ mAddressedPlayer.getPlaybackState());
}
if (previousTrack != null) {
removeUnusedArtwork(previousTrack.getCoverArtUuid());
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java b/android/app/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java
index 25df4cd613..8d68409fb2 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java
@@ -86,6 +86,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_LOCALE_CHANGED)) {
+ if (DBG) Log.d(TAG, "Locale has updated");
if (sBluetoothMediaBrowserService == null) return;
MediaSessionCompat session = sBluetoothMediaBrowserService.getSession();
MediaControllerCompat controller = session.getController();
@@ -106,7 +107,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
*/
@Override
public void onCreate() {
- if (DBG) Log.d(TAG, "onCreate");
+ if (DBG) Log.d(TAG, "Service Created");
super.onCreate();
// Create and configure the MediaSessionCompat
@@ -128,6 +129,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
@Override
public void onDestroy() {
+ if (DBG) Log.d(TAG, "Service Destroyed");
unregisterReceiver(mReceiver);
mReceiver = null;
}
@@ -191,6 +193,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
AvrcpControllerService avrcpControllerService =
AvrcpControllerService.getAvrcpControllerService();
if (avrcpControllerService == null) {
+ Log.w(TAG, "getContents(id=" + parentMediaId + "): AVRCP Controller Service not ready");
return new BrowseResult(new ArrayList(0), BrowseResult.ERROR_NO_AVRCP_SERVICE);
} else {
return avrcpControllerService.getContents(parentMediaId);
@@ -227,7 +230,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
@Override
public synchronized void onLoadChildren(final String parentMediaId,
final Result<List<MediaItem>> result) {
- if (DBG) Log.d(TAG, "onLoadChildren parentMediaId= " + parentMediaId);
+ if (DBG) Log.d(TAG, "Request for contents, id= " + parentMediaId);
BrowseResult contents = getContents(parentMediaId);
byte status = contents.getStatus();
List<MediaItem> results = contents.getResults();
@@ -236,8 +239,8 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
result.detach();
} else {
if (DBG) {
- Log.d(TAG, "id= " + parentMediaId + ", status= " + contents.getStatusString()
- + ", results=" + results);
+ Log.d(TAG, "Received Contents, id= " + parentMediaId + ", status= "
+ + contents.getStatusString() + ", results=" + results);
}
result.sendResult(results);
}
@@ -245,7 +248,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
@Override
public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
- if (DBG) Log.d(TAG, "onGetRoot");
+ Log.i(TAG, "Browser Client Connection Request, client='" + clientPackageName + "')");
Bundle style = getDefaultStyle();
return new BrowserRoot(BrowseTree.ROOT, style);
}
@@ -263,6 +266,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
} else {
mSession.setQueue(null);
}
+ if (DBG) Log.d(TAG, "Now Playing List Changed, queue=" + mMediaQueue);
}
private void clearNowPlayingQueue() {
@@ -275,6 +279,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
if (node.getScope() == AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING) {
sBluetoothMediaBrowserService.updateNowPlayingQueue(node);
} else {
+ if (DBG) Log.d(TAG, "Browse Node contents changed, node=" + node);
sBluetoothMediaBrowserService.notifyChildrenChanged(node.getID());
}
}
@@ -293,7 +298,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
}
static synchronized void trackChanged(AvrcpItem track) {
- if (DBG) Log.d(TAG, "trackChanged setMetadata=" + track);
+ if (DBG) Log.d(TAG, "Track Changed, track=" + track);
if (sBluetoothMediaBrowserService != null) {
if (track != null) {
sBluetoothMediaBrowserService.mSession.setMetadata(track.toMediaMetadata());
@@ -307,7 +312,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
}
static synchronized void notifyChanged(PlaybackStateCompat playbackState) {
- Log.d(TAG, "notifyChanged PlaybackState" + playbackState);
+ if (DBG) Log.d(TAG, "Playback State Changed, state=" + playbackState);
if (sBluetoothMediaBrowserService != null) {
sBluetoothMediaBrowserService.mSession.setPlaybackState(playbackState);
} else {
@@ -340,15 +345,16 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
/**
* Get playback state
*/
- public static synchronized int getPlaybackState() {
+ public static synchronized PlaybackStateCompat getPlaybackState() {
if (sBluetoothMediaBrowserService != null) {
- PlaybackStateCompat currentPlaybackState =
- sBluetoothMediaBrowserService.mSession.getController().getPlaybackState();
- if (currentPlaybackState != null) {
- return currentPlaybackState.getState();
- }
+ MediaSessionCompat session = sBluetoothMediaBrowserService.getSession();
+ if (session == null) return null;
+ MediaControllerCompat controller = session.getController();
+ PlaybackStateCompat playbackState =
+ controller == null ? null : controller.getPlaybackState();
+ return playbackState;
}
- return PlaybackStateCompat.STATE_ERROR;
+ return null;
}
/**
diff --git a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java
index faa10ccadc..73530ed150 100644
--- a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java
+++ b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java
@@ -24,7 +24,6 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHearingAid;
-import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothSinkAudioPolicy;
import android.content.BroadcastReceiver;
@@ -68,12 +67,9 @@ import java.util.Set;
* devices is more than one, the rules below will apply.
* 2) The selected A2DP active device is the one used for AVRCP as well.
* 3) The HFP active device might be different from the A2DP active device.
- * 4) The Active Device Manager always listens for ACTION_ACTIVE_DEVICE_CHANGED
- * broadcasts for each profile:
- * - BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED for LE audio
- * If such broadcast is received (e.g., triggered indirectly by user
- * action on the UI), the device in the received broadcast is marked
- * as the current active device for that profile.
+ * 4) The Active Device Manager always listens for the change of active devices.
+ * When it changed (e.g., triggered indirectly by user action on the UI),
+ * the new active device is marked as the current active device for that profile.
* 5) If there is a HearingAid active device, then A2DP, HFP and LE audio active devices
* must be set to null (i.e., A2DP, HFP and LE audio cannot have active devices).
* The reason is that A2DP, HFP or LE audio cannot be used together with HearingAid.
@@ -88,11 +84,8 @@ import java.util.Set;
* 7) If the currently active device (per profile) is disconnected, the
* Active Device Manager just marks that the profile has no active device,
* and the lastly activated BT device that is still connected would be selected.
- * 8) If there is already an active device, and the corresponding
- * ACTION_ACTIVE_DEVICE_CHANGED broadcast is received, the device
- * contained in the broadcast is marked as active. However, if
- * the contained device is null, the corresponding profile is marked
- * as having no active device.
+ * 8) If there is already an active device, however, if active device change notified
+ * with a null device, the corresponding profile is marked as having no active device.
* 9) If a wired audio device is connected, the audio output is switched
* by the Audio Framework itself to that device. We detect this here,
* and the active device for each profile (A2DP/HFP/HearingAid/LE audio) is set
@@ -151,7 +144,6 @@ public class ActiveDeviceManager {
private BluetoothDevice mClassicDeviceToBeActivated = null;
private BluetoothDevice mClassicDeviceNotToBeActivated = null;
- // Broadcast receiver for all changes
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -168,32 +160,6 @@ public class ActiveDeviceManager {
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
int currentState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
mHandler.post(() -> handleAdapterStateChanged(currentState));
- return;
- }
-
- final BluetoothDevice device = intent.getParcelableExtra(
- BluetoothDevice.EXTRA_DEVICE, BluetoothDevice.class);
- final int previousState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1);
- final int currentState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
-
- if (currentState != -1 && previousState == currentState) {
- return;
- }
-
- switch (action) {
- case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED:
- if (currentState == BluetoothProfile.STATE_CONNECTED) {
- mHandler.post(() -> handleLeAudioConnected(device));
- } else if (previousState == BluetoothProfile.STATE_CONNECTED) {
- mHandler.post(() -> handleLeAudioDisconnected(device));
- }
- break;
- case BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED:
- mHandler.post(() -> handleLeAudioActiveDeviceChanged(device));
- break;
- default:
- Log.e(TAG, "Received unexpected intent, action=" + action);
- break;
}
}
};
@@ -247,6 +213,30 @@ public class ActiveDeviceManager {
}
/**
+ * Called when LE audio connection state changed by LeAudioService
+ *
+ * @param device The device of which connection state was changed
+ * @param prevState The previous connection state of the device
+ * @param newState The new connection state of the device
+ */
+ public void leAudioConnectionStateChanged(BluetoothDevice device, int prevState, int newState) {
+ if (newState == BluetoothProfile.STATE_CONNECTED) {
+ mHandler.post(() -> handleLeAudioConnected(device));
+ } else if (prevState == BluetoothProfile.STATE_CONNECTED) {
+ mHandler.post(() -> handleLeAudioDisconnected(device));
+ }
+ }
+
+ /**
+ * Called when LE audio active state changed by LeAudioService
+ *
+ * @param device The device currently activated. {@code null} if no LE audio device activated
+ */
+ public void leAudioActiveStateChanged(BluetoothDevice device) {
+ mHandler.post(() -> handleLeAudioActiveDeviceChanged(device));
+ }
+
+ /**
* Called when HearingAid connection state changed by HearingAidService
*
* @param device The device of which connection state was changed
@@ -848,8 +838,6 @@ public class ActiveDeviceManager {
IntentFilter filter = new IntentFilter();
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
- filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED);
- filter.addAction(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED);
mAdapterService.registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED);
mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, mHandler);
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
index 5225557914..f84cc69ff4 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
@@ -79,11 +79,9 @@ import android.bluetooth.UidTraffic;
import android.companion.CompanionDeviceManager;
import android.content.AttributionSource;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
@@ -122,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;
@@ -284,17 +283,29 @@ public class AdapterService extends Service {
return sAdapterService;
}
- private static synchronized void setAdapterService(AdapterService instance) {
- Log.d(TAG, "setAdapterService() - trying to set service to " + instance);
+ /** Allow test to set an AdapterService to be return by AdapterService.getAdapterService() */
+ @VisibleForTesting
+ public static synchronized void setAdapterService(AdapterService instance) {
if (instance == null) {
+ Log.e(TAG, "setAdapterService() - instance is null");
return;
}
+ Log.d(TAG, "setAdapterService() - set service to " + instance);
sAdapterService = instance;
}
- private static synchronized void clearAdapterService(AdapterService current) {
- if (sAdapterService == current) {
+ /** Clear test Adapter service. See {@code setAdapterService} */
+ @VisibleForTesting
+ public static synchronized void clearAdapterService(AdapterService instance) {
+ if (sAdapterService == instance) {
+ Log.d(TAG, "clearAdapterService() - This adapter was cleared " + instance);
sAdapterService = null;
+ } else {
+ Log.d(
+ TAG,
+ "clearAdapterService() - incorrect cleared adapter."
+ + (" Instance=" + instance)
+ + (" vs sAdapterService=" + sAdapterService));
}
}
@@ -370,7 +381,7 @@ public class AdapterService extends Service {
private BassClientService mBassClientService;
private BatteryService mBatteryService;
private BluetoothQualityReportNativeInterface mBluetoothQualityReportNativeInterface;
- private IBluetoothGatt mBluetoothGatt;
+ private GattService mGattService;
private volatile boolean mTestModeEnabled = false;
@@ -424,8 +435,6 @@ public class AdapterService extends Service {
private static final int MESSAGE_PROFILE_SERVICE_REGISTERED = 2;
private static final int MESSAGE_PROFILE_SERVICE_UNREGISTERED = 3;
private static final int MESSAGE_PREFERRED_AUDIO_PROFILES_AUDIO_FRAMEWORK_TIMEOUT = 4;
- private static final int MESSAGE_ON_PROFILE_SERVICE_BIND = 5;
- private static final int MESSAGE_ON_PROFILE_SERVICE_UNBIND = 6;
class AdapterServiceHandler extends Handler {
AdapterServiceHandler(Looper looper) {
@@ -449,14 +458,6 @@ public class AdapterService extends Service {
verboseLog("handleMessage() - MESSAGE_PROFILE_SERVICE_UNREGISTERED");
unregisterProfileService((ProfileService) msg.obj);
break;
- case MESSAGE_ON_PROFILE_SERVICE_BIND:
- verboseLog("handleMessage() - MESSAGE_ON_PROFILE_SERVICE_BIND");
- onGattBind((IBinder) msg.obj);
- break;
- case MESSAGE_ON_PROFILE_SERVICE_UNBIND:
- verboseLog("handleMessage() - MESSAGE_ON_PROFILE_SERVICE_UNBIND");
- onGattUnbind();
- break;
case MESSAGE_PREFERRED_AUDIO_PROFILES_AUDIO_FRAMEWORK_TIMEOUT:
errorLog(
"handleMessage() - "
@@ -496,22 +497,6 @@ public class AdapterService extends Service {
mRegisteredProfiles.remove(profile);
}
- private void onGattBind(IBinder service) {
- mBluetoothGatt = IBluetoothGatt.Stub.asInterface(service);
- try {
- mBluetoothGatt.startService();
- } catch (RemoteException e) {
- Log.e(TAG, "onGattBind: RemoteException", e);
- }
- }
-
- private void onGattUnbind() {
- mBluetoothGatt = null;
- Log.e(
- TAG,
- "onGattUnbind: Gatt service has disconnected from AdapterService unexpectedly");
- }
-
private void processProfileServiceStateChanged(ProfileService profile, int state) {
switch (state) {
case BluetoothAdapter.STATE_ON:
@@ -639,7 +624,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();
@@ -716,7 +703,6 @@ public class AdapterService extends Service {
mBluetoothSocketManagerBinder = new BluetoothSocketManagerBinder(this);
mActivityAttributionService = new ActivityAttributionService();
- mActivityAttributionService.start();
setAdapterService(this);
@@ -1003,47 +989,11 @@ public class AdapterService extends Service {
}
}
- class GattServiceConnection implements ServiceConnection {
- public void onServiceConnected(ComponentName componentName, IBinder service) {
- String name = componentName.getClassName();
- if (DBG) {
- Log.d(TAG, "GattServiceConnection.onServiceConnected: " + name);
- }
- if (!name.equals(GattService.class.getName())) {
- Log.e(TAG, "Unknown service connected: " + name);
- return;
- }
- mHandler.obtainMessage(MESSAGE_ON_PROFILE_SERVICE_BIND, service).sendToTarget();
- }
-
- public void onServiceDisconnected(ComponentName componentName) {
- // Called if we unexpectedly disconnect. This should never happen.
- String name = componentName.getClassName();
- Log.e(TAG, "GattServiceConnection.onServiceDisconnected: " + name);
- if (!name.equals(GattService.class.getName())) {
- Log.e(TAG, "Unknown service disconnected: " + name);
- return;
- }
- mHandler.sendEmptyMessage(MESSAGE_ON_PROFILE_SERVICE_UNBIND);
- }
- }
-
- private GattServiceConnection mGattConnection = new GattServiceConnection();
-
private void startGattProfileService() {
mStartedProfiles.add(GattService.class.getSimpleName());
- Intent intent = new Intent(this, GattService.class);
- if (!bindServiceAsUser(
- intent,
- mGattConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
- UserHandle.CURRENT)) {
- // This should never happen
- // unbindService will be called during stopGattProfileService triggered by AdapterState
- Log.e(TAG, "Error while binding to gatt. This Bluetooth session will timeout");
- unbindService(mGattConnection);
- }
+ mGattService = new GattService(this);
+ ((ProfileService) mGattService).doStart();
}
private void stopGattProfileService() {
@@ -1054,15 +1004,10 @@ public class AdapterService extends Service {
}
mStartedProfiles.remove(GattService.class.getSimpleName());
-
- try {
- if (mBluetoothGatt != null) {
- mBluetoothGatt.stopService();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "stopGattProfileService: RemoteException", e);
+ if (mGattService != null) {
+ ((ProfileService) mGattService).doStop();
+ mGattService = null;
}
- unbindService(mGattConnection);
}
private void invalidateBluetoothGetStateCache() {
@@ -1360,10 +1305,6 @@ public class AdapterService extends Service {
mSdpManager = null;
}
- if (mActivityAttributionService != null) {
- mActivityAttributionService.cleanup();
- }
-
if (mNativeAvailable) {
debugLog("cleanup() - Cleaning up adapter native");
cleanupNative();
@@ -5014,7 +4955,7 @@ public class AdapterService extends Service {
if (service == null) {
return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
}
- if (!callerIsSystem(TAG, "setPreferredAudioProfiles")) {
+ if (!callerIsSystem(TAG, "notifyActiveDeviceChangeApplied")) {
return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ALLOWED;
}
requireNonNull(device);
@@ -5246,6 +5187,7 @@ public class AdapterService extends Service {
try {
AdapterService service = getService();
if (service != null) {
+ enforceBluetoothPrivilegedPermission(service);
service.unregAllGattClient(source);
}
receiver.send(null);
@@ -6885,16 +6827,15 @@ public class AdapterService extends Service {
}
IBluetoothGatt getBluetoothGatt() {
- return mBluetoothGatt;
+ if (mGattService == null) {
+ return null;
+ }
+ return IBluetoothGatt.Stub.asInterface(((ProfileService) mGattService).getBinder());
}
void unregAllGattClient(AttributionSource source) {
- if (mBluetoothGatt != null) {
- try {
- mBluetoothGatt.unregAll(source);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to disconnect all apps.", e);
- }
+ if (mGattService != null) {
+ mGattService.unregAll(source);
}
}
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/Config.java b/android/app/src/com/android/bluetooth/btservice/Config.java
index bc0ed8408c..caa1a0004a 100644
--- a/android/app/src/com/android/bluetooth/btservice/Config.java
+++ b/android/app/src/com/android/bluetooth/btservice/Config.java
@@ -56,6 +56,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Set;
public class Config {
@@ -171,9 +172,14 @@ public class Config {
profile.mSupported = enabled;
}
}
+ if (enabled) {
+ sSupportedProfiles.add(profileClass);
+ } else {
+ sSupportedProfiles.remove(profileClass);
+ }
}
- private static Class[] sSupportedProfiles = new Class[0];
+ private static List<Class> sSupportedProfiles = new ArrayList<>();
private static boolean sIsGdEnabledUptoScanningLayer = false;
@@ -211,15 +217,20 @@ public class Config {
setProfileEnabled(HearingAidService.class, false);
}
- ArrayList<Class> profiles = new ArrayList<>(PROFILE_SERVICES_AND_FLAGS.length);
- for (ProfileConfig config : PROFILE_SERVICES_AND_FLAGS) {
- Log.i(TAG, "init: profile=" + config.mClass.getSimpleName() + ", enabled="
- + config.mSupported);
- if (config.mSupported) {
- profiles.add(config.mClass);
+ synchronized (sSupportedProfiles) {
+ sSupportedProfiles.clear();
+ for (ProfileConfig config : PROFILE_SERVICES_AND_FLAGS) {
+ Log.i(
+ TAG,
+ "init: profile="
+ + config.mClass.getSimpleName()
+ + ", enabled="
+ + config.mSupported);
+ if (config.mSupported) {
+ sSupportedProfiles.add(config.mClass);
+ }
}
}
- sSupportedProfiles = profiles.toArray(new Class[profiles.size()]);
if (ctx == null) {
return;
@@ -253,19 +264,17 @@ public class Config {
* Remove the input profiles from the supported list.
*/
static void removeProfileFromSupportedList(HashSet<Class> nonSupportedProfiles) {
- ArrayList<Class> profilesList = new ArrayList<Class>(Arrays.asList(sSupportedProfiles));
- Iterator<Class> iter = profilesList.iterator();
-
- while (iter.hasNext()) {
- Class profileClass = iter.next();
-
- if (nonSupportedProfiles.contains(profileClass)) {
- iter.remove();
- Log.v(TAG, "Remove " + profileClass.getSimpleName() + " from supported list.");
+ synchronized (sSupportedProfiles) {
+ Iterator<Class> iter = sSupportedProfiles.iterator();
+ while (iter.hasNext()) {
+ Class profileClass = iter.next();
+
+ if (nonSupportedProfiles.contains(profileClass)) {
+ iter.remove();
+ Log.v(TAG, "Remove " + profileClass.getSimpleName() + " from supported list.");
+ }
}
}
-
- sSupportedProfiles = profilesList.toArray(new Class[profilesList.size()]);
}
static void updateSupportedProfileMask(Boolean enable, Class profile, int supportedProfile) {
@@ -286,7 +295,9 @@ public class Config {
}
static Class[] getSupportedProfiles() {
- return sSupportedProfiles;
+ synchronized (sSupportedProfiles) {
+ return sSupportedProfiles.toArray(new Class[0]);
+ }
}
static boolean isGdEnabledUpToScanningLayer() {
diff --git a/android/app/src/com/android/bluetooth/btservice/ProfileService.java b/android/app/src/com/android/bluetooth/btservice/ProfileService.java
index 5795847d1b..acd72c7c69 100644
--- a/android/app/src/com/android/bluetooth/btservice/ProfileService.java
+++ b/android/app/src/com/android/bluetooth/btservice/ProfileService.java
@@ -18,6 +18,8 @@ package com.android.bluetooth.btservice;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static java.util.Objects.requireNonNull;
+
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.app.Service;
@@ -180,6 +182,11 @@ public abstract class ProfileService extends Service {
return mBinder;
}
+ IBinder getBinder() {
+ requireNonNull(mBinder, "Binder is null. onCreate need to be called first");
+ return mBinder;
+ }
+
@Override
// Suppressed since this is called from framework
@SuppressLint("AndroidFrameworkRequiresPermission")
@@ -295,7 +302,7 @@ public abstract class ProfileService extends Service {
android.Manifest.permission.MANAGE_USERS,
android.Manifest.permission.INTERACT_ACROSS_USERS
})
- protected void doStart() {
+ void doStart() {
Log.v(mName, "doStart");
if (mAdapter == null) {
Log.w(mName, "Can't start profile service: device does not have BT");
@@ -321,7 +328,7 @@ public abstract class ProfileService extends Service {
mAdapterService.onProfileServiceStateChanged(this, BluetoothAdapter.STATE_ON);
}
- protected void doStop() {
+ void doStop() {
Log.v(mName, "doStop");
if (mAdapterService == null || mAdapterService.isStartedProfile(mName)) {
Log.w(mName, "Unexpectedly do Stop, don't stop.");
diff --git a/android/app/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionNativeInterface.java b/android/app/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionNativeInterface.java
index b9cb9d778d..7755ce2d2c 100644
--- a/android/app/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionNativeInterface.java
@@ -21,26 +21,15 @@
*/
package com.android.bluetooth.btservice.activityattribution;
-import android.util.Log;
-
import com.android.internal.annotations.GuardedBy;
-import java.util.Arrays;
-
/** ActivityAttribution Native Interface to/from JNI. */
public class ActivityAttributionNativeInterface {
- private static final boolean DBG = false;
- private static final String TAG = "ActivityAttributionNativeInterface";
-
@GuardedBy("INSTANCE_LOCK")
private static ActivityAttributionNativeInterface sInstance;
private static final Object INSTANCE_LOCK = new Object();
- static {
- classInitNative();
- }
-
/** Get singleton instance. */
public static ActivityAttributionNativeInterface getInstance() {
synchronized (INSTANCE_LOCK) {
@@ -51,40 +40,11 @@ public class ActivityAttributionNativeInterface {
}
}
- /** Initializes the native interface. */
- public void init() {
- initNative();
- }
-
- /** Cleanup the native interface. */
- public void cleanup() {
- cleanupNative();
- }
-
/** Notify the UID and package name of the app, and the address of associated active device */
public void notifyActivityAttributionInfo(int uid, String packageName, String deviceAddress) {
notifyActivityAttributionInfoNative(uid, packageName, deviceAddress);
}
- // Callbacks from the native stack back into the Java framework.
- // All callbacks are routed via the Service which will disambiguate which
- // state machine the message should be routed to.
-
- private void onWakeup(int activity, byte[] address) {
- Log.i(TAG, "onWakeup() BTAA: " + activity);
- }
-
- private void onActivityLogsReady(byte[] logs) {
- Log.i(TAG, "onActivityLogsReady() BTAA: " + Arrays.toString(logs));
- }
-
- // Native methods that call into the JNI interface
- private static native void classInitNative();
-
- private native void initNative();
-
- private native void cleanupNative();
-
private native void notifyActivityAttributionInfoNative(
- int uid, String packageName, String deviceAddress);
+ int uid, String packageName, String deviceAddress);
}
diff --git a/android/app/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionService.java b/android/app/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionService.java
index 033459812a..5194a25313 100644
--- a/android/app/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionService.java
+++ b/android/app/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionService.java
@@ -16,108 +16,31 @@
package com.android.bluetooth.btservice.activityattribution;
-import android.util.Log;
+import static java.util.Objects.requireNonNull;
-import java.util.Objects;
+import android.util.Log;
/**
* Service used for attributes wakeup, wakelock and Bluetooth traffic into per-app and per-device
* based activities.
*/
public class ActivityAttributionService {
- private boolean mCleaningUp;
- private static ActivityAttributionService sActivityAttributionService;
- private static final boolean DBG = false;
- private static final String TAG = "ActivityAttributionService";
-
- ActivityAttributionNativeInterface mActivityAttributionNativeInterface;
-
- /** Start and initialize the Activity Attribution service. */
- public void start() {
- debugLog("start()");
-
- if (sActivityAttributionService != null) {
- Log.e(TAG, "start() called twice");
- return;
- }
-
- mActivityAttributionNativeInterface =
- Objects.requireNonNull(
- ActivityAttributionNativeInterface.getInstance(),
- "ActivityAttributionNativeInterface "
- + "cannot be null when ActivityAttributionService starts");
-
- // Mark service as started
- setActivityAttributionService(this);
- }
-
- /** Cleans up the Activity Attribution service. */
- public void cleanup() {
- debugLog("cleanup");
- if (mCleaningUp) {
- debugLog("already doing cleanup");
- return;
- }
-
- mCleaningUp = true;
-
- if (sActivityAttributionService == null) {
- debugLog("cleanup() called before start()");
- return;
- }
-
- // Mark service as stopped
- setActivityAttributionService(null);
+ private static final String TAG = ActivityAttributionService.class.getSimpleName();
- // Cleanup native interface
- mActivityAttributionNativeInterface.cleanup();
- mActivityAttributionNativeInterface = null;
- }
-
- /** Get the ActivityAttributionService instance */
- public static synchronized ActivityAttributionService getActivityAttributionService() {
- if (sActivityAttributionService == null) {
- Log.w(TAG, "getActivityAttributionService(): service is NULL");
- return null;
- }
-
- if (!sActivityAttributionService.isAvailable()) {
- Log.w(TAG, "getActivityAttributionService(): service is not available");
- return null;
- }
- return sActivityAttributionService;
- }
-
- /** Init JNI */
- public void initJni() {
- debugLog("initJni()");
- // Initialize native interface
- mActivityAttributionNativeInterface.init();
- }
+ private final ActivityAttributionNativeInterface mActivityAttributionNativeInterface =
+ requireNonNull(
+ ActivityAttributionNativeInterface.getInstance(),
+ "ActivityAttributionNativeInterface cannot be null");
/** Notify the UID and package name of the app, and the address of associated active device */
public void notifyActivityAttributionInfo(int uid, String packageName, String deviceAddress) {
- Log.d(TAG, "notifyActivityAttributionInfo"
- + " UID=" + uid
- + " packageName=" + packageName
- + " deviceAddress=" + deviceAddress);
+ Log.d(
+ TAG,
+ "notifyActivityAttributionInfo()"
+ + (" UID=" + uid)
+ + (" packageName=" + packageName)
+ + (" deviceAddress=" + deviceAddress));
mActivityAttributionNativeInterface.notifyActivityAttributionInfo(
uid, packageName, deviceAddress);
}
-
- private boolean isAvailable() {
- return !mCleaningUp;
- }
-
- private static synchronized void setActivityAttributionService(
- ActivityAttributionService instance) {
- debugLog("setActivityAttributionService(): set to: " + instance);
- sActivityAttributionService = instance;
- }
-
- private static void debugLog(String msg) {
- if (DBG) {
- Log.d(TAG, msg);
- }
- }
}
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/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
index c2dbaaffce..2809b08d77 100644
--- a/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
+++ b/android/app/src/com/android/bluetooth/csip/CsipSetCoordinatorService.java
@@ -847,7 +847,7 @@ public class CsipSetCoordinatorService extends ProfileService {
intent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- sendBroadcast(intent, BLUETOOTH_PRIVILEGED);
+ sendOrderedBroadcast(intent, BLUETOOTH_PRIVILEGED);
/* Notify registered parties */
handleSetMemberAvailable(device, groupId);
@@ -890,7 +890,7 @@ public class CsipSetCoordinatorService extends ProfileService {
if (intent != null) {
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- sendBroadcast(intent, BLUETOOTH_PRIVILEGED);
+ sendOrderedBroadcast(intent, BLUETOOTH_PRIVILEGED);
}
synchronized (mStateMachines) {
diff --git a/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java b/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java
index e105abff5b..a632ef9210 100644
--- a/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java
+++ b/android/app/src/com/android/bluetooth/gatt/AdvertiseManager.java
@@ -51,20 +51,23 @@ public class AdvertiseManager {
private final GattService mService;
private final AdapterService mAdapterService;
+ private final AdvertiseManagerNativeInterface mNativeInterface;
private final AdvertiserMap mAdvertiserMap;
private Handler mHandler;
Map<IBinder, AdvertiserInfo> mAdvertisers = Collections.synchronizedMap(new HashMap<>());
static int sTempRegistrationId = -1;
- /**
- * Constructor of {@link AdvertiseManager}.
- */
- AdvertiseManager(GattService service, AdapterService adapterService,
+ /** Constructor of {@link AdvertiseManager}. */
+ AdvertiseManager(
+ GattService service,
+ AdvertiseManagerNativeInterface nativeInterface,
+ AdapterService adapterService,
AdvertiserMap advertiserMap) {
if (DBG) {
Log.d(TAG, "advertise manager created");
}
mService = service;
+ mNativeInterface = nativeInterface;
mAdapterService = adapterService;
mAdvertiserMap = advertiserMap;
}
@@ -73,7 +76,7 @@ public class AdvertiseManager {
* Start a {@link HandlerThread} that handles advertising operations.
*/
void start() {
- initializeNative();
+ mNativeInterface.init(this);
HandlerThread thread = new HandlerThread("BluetoothAdvertiseManager");
thread.start();
mHandler = new Handler(thread.getLooper());
@@ -83,7 +86,7 @@ public class AdvertiseManager {
if (DBG) {
Log.d(TAG, "cleanup()");
}
- cleanupNative();
+ mNativeInterface.cleanup();
mAdvertisers.clear();
sTempRegistrationId = -1;
@@ -157,7 +160,7 @@ public class AdvertiseManager {
if (entry == null) {
Log.i(TAG, "onAdvertisingSetStarted() - no callback found for regId " + regId);
// Advertising set was stopped before it was properly registered.
- stopAdvertisingSetNative(advertiserId);
+ mNativeInterface.stopAdvertisingSet(advertiserId);
return;
}
@@ -252,8 +255,15 @@ public class AdvertiseManager {
mAdvertiserMap.recordAdvertiseStart(cbId, parameters, advertiseData,
scanResponse, periodicParameters, periodicData, duration, maxExtAdvEvents);
- startAdvertisingSetNative(parameters, advDataBytes, scanResponseBytes,
- periodicParameters, periodicDataBytes, duration, maxExtAdvEvents, cbId,
+ mNativeInterface.startAdvertisingSet(
+ parameters,
+ advDataBytes,
+ scanResponseBytes,
+ periodicParameters,
+ periodicDataBytes,
+ duration,
+ maxExtAdvEvents,
+ cbId,
serverIf);
} catch (IllegalArgumentException e) {
@@ -289,7 +299,7 @@ public class AdvertiseManager {
Log.w(TAG, "getOwnAddress() - bad advertiserId " + advertiserId);
return;
}
- getOwnAddressNative(advertiserId);
+ mNativeInterface.getOwnAddress(advertiserId);
}
void stopAdvertisingSet(IAdvertisingSetCallback callback) {
@@ -313,7 +323,7 @@ public class AdvertiseManager {
return;
}
- stopAdvertisingSetNative(advertiserId);
+ mNativeInterface.stopAdvertisingSet(advertiserId);
try {
callback.onAdvertisingSetStopped(advertiserId);
@@ -330,7 +340,7 @@ public class AdvertiseManager {
Log.w(TAG, "enableAdvertisingSet() - bad advertiserId " + advertiserId);
return;
}
- enableAdvertisingSetNative(advertiserId, enable, duration, maxExtAdvEvents);
+ mNativeInterface.enableAdvertisingSet(advertiserId, enable, duration, maxExtAdvEvents);
mAdvertiserMap.enableAdvertisingSet(advertiserId,
enable, duration, maxExtAdvEvents);
@@ -344,8 +354,8 @@ public class AdvertiseManager {
}
String deviceName = AdapterService.getAdapterService().getName();
try {
- setAdvertisingDataNative(advertiserId,
- AdvertiseHelper.advertiseDataToBytes(data, deviceName));
+ mNativeInterface.setAdvertisingData(
+ advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName));
mAdvertiserMap.setAdvertisingData(advertiserId, data);
} catch (IllegalArgumentException e) {
@@ -366,8 +376,8 @@ public class AdvertiseManager {
}
String deviceName = AdapterService.getAdapterService().getName();
try {
- setScanResponseDataNative(advertiserId,
- AdvertiseHelper.advertiseDataToBytes(data, deviceName));
+ mNativeInterface.setScanResponseData(
+ advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName));
mAdvertiserMap.setScanResponseData(advertiserId, data);
} catch (IllegalArgumentException e) {
@@ -386,7 +396,7 @@ public class AdvertiseManager {
Log.w(TAG, "setAdvertisingParameters() - bad advertiserId " + advertiserId);
return;
}
- setAdvertisingParametersNative(advertiserId, parameters);
+ mNativeInterface.setAdvertisingParameters(advertiserId, parameters);
mAdvertiserMap.setAdvertisingParameters(advertiserId, parameters);
}
@@ -398,7 +408,7 @@ public class AdvertiseManager {
Log.w(TAG, "setPeriodicAdvertisingParameters() - bad advertiserId " + advertiserId);
return;
}
- setPeriodicAdvertisingParametersNative(advertiserId, parameters);
+ mNativeInterface.setPeriodicAdvertisingParameters(advertiserId, parameters);
mAdvertiserMap.setPeriodicAdvertisingParameters(advertiserId, parameters);
}
@@ -411,8 +421,8 @@ public class AdvertiseManager {
}
String deviceName = AdapterService.getAdapterService().getName();
try {
- setPeriodicAdvertisingDataNative(advertiserId,
- AdvertiseHelper.advertiseDataToBytes(data, deviceName));
+ mNativeInterface.setPeriodicAdvertisingData(
+ advertiserId, AdvertiseHelper.advertiseDataToBytes(data, deviceName));
mAdvertiserMap.setPeriodicAdvertisingData(advertiserId, data);
} catch (IllegalArgumentException e) {
@@ -431,7 +441,7 @@ public class AdvertiseManager {
Log.w(TAG, "setPeriodicAdvertisingEnable() - bad advertiserId " + advertiserId);
return;
}
- setPeriodicAdvertisingEnableNative(advertiserId, enable);
+ mNativeInterface.setPeriodicAdvertisingEnable(advertiserId, enable);
}
void onAdvertisingDataSet(int advertiserId, int status) throws Exception {
@@ -538,40 +548,4 @@ public class AdvertiseManager {
stats.onPeriodicAdvertiseEnabled(enable);
}
}
-
- static {
- classInitNative();
- }
-
- private static native void classInitNative();
-
- private native void initializeNative();
-
- private native void cleanupNative();
-
- private native void startAdvertisingSetNative(AdvertisingSetParameters parameters,
- byte[] advertiseData, byte[] scanResponse,
- PeriodicAdvertisingParameters periodicParameters, byte[] periodicData, int duration,
- int maxExtAdvEvents, int regId, int serverIf);
-
- private native void getOwnAddressNative(int advertiserId);
-
- private native void stopAdvertisingSetNative(int advertiserId);
-
- private native void enableAdvertisingSetNative(int advertiserId, boolean enable, int duration,
- int maxExtAdvEvents);
-
- private native void setAdvertisingDataNative(int advertiserId, byte[] data);
-
- private native void setScanResponseDataNative(int advertiserId, byte[] data);
-
- private native void setAdvertisingParametersNative(int advertiserId,
- AdvertisingSetParameters parameters);
-
- private native void setPeriodicAdvertisingParametersNative(int advertiserId,
- PeriodicAdvertisingParameters parameters);
-
- private native void setPeriodicAdvertisingDataNative(int advertiserId, byte[] data);
-
- private native void setPeriodicAdvertisingEnableNative(int advertiserId, boolean enable);
}
diff --git a/android/app/src/com/android/bluetooth/gatt/AdvertiseManagerNativeInterface.java b/android/app/src/com/android/bluetooth/gatt/AdvertiseManagerNativeInterface.java
new file mode 100644
index 0000000000..7529bdb86d
--- /dev/null
+++ b/android/app/src/com/android/bluetooth/gatt/AdvertiseManagerNativeInterface.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.bluetooth.gatt;
+
+import android.bluetooth.le.AdvertisingSetParameters;
+import android.bluetooth.le.PeriodicAdvertisingParameters;
+
+import androidx.annotation.VisibleForTesting;
+
+/** Native interface for AdvertiseManager */
+@VisibleForTesting
+public class AdvertiseManagerNativeInterface {
+ AdvertiseManager mManager;
+
+ void init(AdvertiseManager manager) {
+ mManager = manager;
+ initializeNative();
+ }
+
+ void cleanup() {
+ cleanupNative();
+ mManager = null;
+ }
+
+ void startAdvertisingSet(
+ AdvertisingSetParameters parameters,
+ byte[] advertiseDataBytes,
+ byte[] scanResponseBytes,
+ PeriodicAdvertisingParameters periodicParameters,
+ byte[] periodicDataBytes,
+ int duration,
+ int maxExtAdvEvents,
+ int cbId,
+ int serverIf) {
+ startAdvertisingSetNative(
+ parameters,
+ advertiseDataBytes,
+ scanResponseBytes,
+ periodicParameters,
+ periodicDataBytes,
+ duration,
+ maxExtAdvEvents,
+ cbId,
+ serverIf);
+ }
+
+ void stopAdvertisingSet(int advertiserId) {
+ stopAdvertisingSetNative(advertiserId);
+ }
+
+ void getOwnAddress(int advertiserId) {
+ getOwnAddressNative(advertiserId);
+ }
+
+ void enableAdvertisingSet(int advertiserId, boolean enable, int duration, int maxExtAdvEvents) {
+ enableAdvertisingSetNative(advertiserId, enable, duration, maxExtAdvEvents);
+ }
+
+ void setAdvertisingData(int advertiserId, byte[] advertiseDataBytes) {
+ setAdvertisingDataNative(advertiserId, advertiseDataBytes);
+ }
+
+ void setScanResponseData(int advertiserId, byte[] advertiseDataBytes) {
+ setScanResponseDataNative(advertiserId, advertiseDataBytes);
+ }
+
+ void setAdvertisingParameters(int advertiserId, AdvertisingSetParameters parameters) {
+ setAdvertisingParametersNative(advertiserId, parameters);
+ }
+
+ void setPeriodicAdvertisingParameters(
+ int advertiserId, PeriodicAdvertisingParameters parameters) {
+ setPeriodicAdvertisingParametersNative(advertiserId, parameters);
+ }
+
+ void setPeriodicAdvertisingData(int advertiserId, byte[] advertiseDataBytes) {
+ setPeriodicAdvertisingDataNative(advertiserId, advertiseDataBytes);
+ }
+
+ void setPeriodicAdvertisingEnable(int advertiserId, boolean enable) {
+ setPeriodicAdvertisingEnableNative(advertiserId, enable);
+ }
+
+ static {
+ classInitNative();
+ }
+
+ void onAdvertisingSetStarted(int regId, int advertiserId, int txPower, int status)
+ throws Exception {
+ mManager.onAdvertisingSetStarted(regId, advertiserId, txPower, status);
+ }
+
+ void onOwnAddressRead(int advertiserId, int addressType, String address) throws Exception {
+ mManager.onOwnAddressRead(advertiserId, addressType, address);
+ }
+
+ void onAdvertisingEnabled(int advertiserId, boolean enable, int status) throws Exception {
+ mManager.onAdvertisingEnabled(advertiserId, enable, status);
+ }
+
+ void onAdvertisingDataSet(int advertiserId, int status) throws Exception {
+ mManager.onAdvertisingDataSet(advertiserId, status);
+ }
+
+ void onScanResponseDataSet(int advertiserId, int status) throws Exception {
+ mManager.onScanResponseDataSet(advertiserId, status);
+ }
+
+ void onAdvertisingParametersUpdated(int advertiserId, int txPower, int status)
+ throws Exception {
+ mManager.onAdvertisingParametersUpdated(advertiserId, txPower, status);
+ }
+
+ void onPeriodicAdvertisingParametersUpdated(int advertiserId, int status) throws Exception {
+ mManager.onPeriodicAdvertisingParametersUpdated(advertiserId, status);
+ }
+
+ void onPeriodicAdvertisingDataSet(int advertiserId, int status) throws Exception {
+ mManager.onPeriodicAdvertisingDataSet(advertiserId, status);
+ }
+
+ void onPeriodicAdvertisingEnabled(int advertiserId, boolean enable, int status)
+ throws Exception {
+ mManager.onPeriodicAdvertisingEnabled(advertiserId, enable, status);
+ }
+
+ private static native void classInitNative();
+
+ private native void initializeNative();
+
+ private native void cleanupNative();
+
+ private native void startAdvertisingSetNative(
+ AdvertisingSetParameters parameters,
+ byte[] advertiseData,
+ byte[] scanResponse,
+ PeriodicAdvertisingParameters periodicParameters,
+ byte[] periodicData,
+ int duration,
+ int maxExtAdvEvents,
+ int regId,
+ int serverIf);
+
+ private native void stopAdvertisingSetNative(int advertiserId);
+
+ private native void getOwnAddressNative(int advertiserId);
+
+ private native void enableAdvertisingSetNative(
+ int advertiserId, boolean enable, int duration, int maxExtAdvEvents);
+
+ private native void setAdvertisingDataNative(int advertiserId, byte[] data);
+
+ private native void setScanResponseDataNative(int advertiserId, byte[] data);
+
+ private native void setAdvertisingParametersNative(
+ int advertiserId, AdvertisingSetParameters parameters);
+
+ private native void setPeriodicAdvertisingParametersNative(
+ int advertiserId, PeriodicAdvertisingParameters parameters);
+
+ private native void setPeriodicAdvertisingDataNative(int advertiserId, byte[] data);
+
+ private native void setPeriodicAdvertisingEnableNative(int advertiserId, boolean enable);
+}
diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java
index eaf11c027f..0156835787 100644
--- a/android/app/src/com/android/bluetooth/gatt/GattService.java
+++ b/android/app/src/com/android/bluetooth/gatt/GattService.java
@@ -56,6 +56,7 @@ import android.bluetooth.le.ScanSettings;
import android.companion.AssociationInfo;
import android.companion.CompanionDeviceManager;
import android.content.AttributionSource;
+import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManager.PackageInfoFlags;
@@ -290,6 +291,11 @@ public class GattService extends ProfileService {
private Handler mTestModeHandler;
private final Object mTestModeLock = new Object();
+ public GattService(Context ctx) {
+ attachBaseContext(ctx);
+ onCreate();
+ }
+
public static boolean isEnabled() {
return BluetoothProperties.isProfileGattEnabled().orElse(true);
}
@@ -341,7 +347,12 @@ public class GattService extends ProfileService {
mBluetoothAdapterProxy = BluetoothAdapterProxy.getInstance();
mCompanionManager = getSystemService(CompanionDeviceManager.class);
mAppOps = getSystemService(AppOpsManager.class);
- mAdvertiseManager = new AdvertiseManager(this, mAdapterService, mAdvertiserMap);
+ mAdvertiseManager =
+ new AdvertiseManager(
+ this,
+ new AdvertiseManagerNativeInterface(),
+ mAdapterService,
+ mAdvertiserMap);
mAdvertiseManager.start();
mScanManager = GattObjectsFactory.getInstance()
@@ -607,34 +618,6 @@ public class GattService extends ProfileService {
}
@Override
- public void startService() {
- GattService service = mService;
- if (service == null) {
- Log.e(TAG, "startService: Service is null");
- return;
- }
- if (!Utils.checkConnectPermissionForDataDelivery(
- service, null, "GattService startService")) {
- return;
- }
- service.doStart();
- }
-
- @Override
- public void stopService() {
- GattService service = mService;
- if (service == null) {
- Log.e(TAG, "stopService: Service is null");
- return;
- }
- if (!Utils.checkConnectPermissionForDataDelivery(
- service, null, "GattService stopService")) {
- return;
- }
- service.doStop();
- }
-
- @Override
public void getDevicesMatchingConnectionStates(int[] states,
AttributionSource attributionSource, SynchronousResultReceiver receiver) {
try {
@@ -1773,15 +1756,6 @@ public class GattService extends ProfileService {
}
@Override
- public void unregAll(AttributionSource attributionSource) {
- GattService service = getService();
- if (service == null) {
- return;
- }
- service.unregAll(attributionSource);
- }
-
- @Override
public void numHwTrackFiltersAvailable(AttributionSource attributionSource,
SynchronousResultReceiver receiver) {
try {
@@ -3430,7 +3404,7 @@ public class GattService extends ProfileService {
}
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
- void unregAll(AttributionSource attributionSource) {
+ public void unregAll(AttributionSource attributionSource) {
for (Integer appId : mClientMap.getAllAppsIds()) {
if (DBG) {
Log.d(TAG, "unreg:" + appId);
diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
index b5691062ee..9c2c7fee48 100644
--- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
@@ -1127,6 +1127,37 @@ public class LeAudioService extends ProfileService {
}
/**
+ * Send broadcast intent about LeAudio connection state changed. This is called by
+ * LeAudioStateMachine.
+ */
+ void notifyConnectionStateChanged(BluetoothDevice device, int newState, int prevState) {
+ if (DBG) {
+ Log.d(
+ TAG,
+ "Notify connection state changed."
+ + device
+ + "("
+ + prevState
+ + " -> "
+ + newState
+ + ")");
+ }
+
+ mAdapterService
+ .getActiveDeviceManager()
+ .leAudioConnectionStateChanged(device, prevState, newState);
+ Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED);
+ intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
+ intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+ intent.addFlags(
+ Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ Utils.sendBroadcast(
+ this, intent, BLUETOOTH_CONNECT, Utils.getTempAllowlistBroadcastOptions());
+ }
+
+ /**
* Send broadcast intent about LeAudio active device.
* This is called when AudioManager confirms, LeAudio device
* is added or removed.
@@ -1138,6 +1169,7 @@ public class LeAudioService extends ProfileService {
+ ". Currently active device is " + mActiveAudioOutDevice);
}
+ mAdapterService.getActiveDeviceManager().leAudioActiveStateChanged(device);
Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioStateMachine.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioStateMachine.java
index a1411f6934..0eb7577d72 100644
--- a/android/app/src/com/android/bluetooth/le_audio/LeAudioStateMachine.java
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioStateMachine.java
@@ -47,15 +47,11 @@
package com.android.bluetooth.le_audio;
import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothProfile;
-import android.content.Intent;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
-import static android.Manifest.permission.BLUETOOTH_CONNECT;
-import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.ProfileService;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.State;
@@ -514,15 +510,7 @@ final class LeAudioStateMachine extends StateMachine {
private void broadcastConnectionState(int newState, int prevState) {
log("Connection state " + mDevice + ": " + profileStateToString(prevState)
+ "->" + profileStateToString(newState));
-
- Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED);
- intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
- intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
- | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- Utils.sendBroadcast(mService, intent, BLUETOOTH_CONNECT,
- Utils.getTempAllowlistBroadcastOptions());
+ mService.notifyConnectionStateChanged(mDevice, newState, prevState);
}
private static String messageWhatToString(int what) {
diff --git a/android/app/tests/unit/AndroidTest.xml b/android/app/tests/unit/AndroidTest.xml
index 37bd75b6eb..212b245d6e 100644
--- a/android/app/tests/unit/AndroidTest.xml
+++ b/android/app/tests/unit/AndroidTest.xml
@@ -30,6 +30,10 @@
<option name="run-command" value="settings put global ble_scan_always_enabled 0" />
<option name="run-command" value="cmd bluetooth_manager disable" />
<option name="run-command" value="cmd bluetooth_manager wait-for-state:STATE_OFF" />
+ <option name="run-command" value="settings put global satellite_mode_radios bluetooth" />
+ <option name="run-command" value="settings put global satellite_mode_enabled 1" />
+ <option name="teardown-command" value="settings delete global satellite_mode_radios" />
+ <option name="teardown-command" value="settings put global satellite_mode_enabled 0" />
<option name="teardown-command" value="cmd bluetooth_manager enable" />
<option name="teardown-command" value="cmd bluetooth_manager wait-for-state:STATE_ON" />
<option name="teardown-command" value="settings put global ble_scan_always_enabled 1" />
diff --git a/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java b/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java
index 4104391c2e..d605ef2f8e 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/TestUtils.java
@@ -39,6 +39,7 @@ import androidx.test.uiautomator.UiDevice;
import com.android.bluetooth.avrcpcontroller.BluetoothMediaBrowserService;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
+import com.android.bluetooth.gatt.GattService;
import org.junit.Assert;
import org.junit.rules.TestRule;
@@ -51,8 +52,6 @@ import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
@@ -93,49 +92,45 @@ public class TestUtils {
/**
* Set the return value of {@link AdapterService#getAdapterService()} to a test specified value
*
- * @param adapterService the designated {@link AdapterService} in test, must not be null, can
- * be mocked or spied
- * @throws NoSuchMethodException when setAdapterService method is not found
- * @throws IllegalAccessException when setAdapterService method cannot be accessed
- * @throws InvocationTargetException when setAdapterService method cannot be invoked, which
- * should never happen since setAdapterService is a static
- * method
+ * @param adapterService the designated {@link AdapterService} in test, must not be null, can be
+ * mocked or spied
*/
- public static void setAdapterService(AdapterService adapterService)
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ public static void setAdapterService(AdapterService adapterService) {
Assert.assertNull("AdapterService.getAdapterService() must be null before setting another"
+ " AdapterService", AdapterService.getAdapterService());
Assert.assertNotNull("Adapter service should not be null", adapterService);
// We cannot mock AdapterService.getAdapterService() with Mockito.
- // Hence we need to use reflection to call a private method to
- // initialize properly the AdapterService.sAdapterService field.
- Method method =
- AdapterService.class.getDeclaredMethod("setAdapterService", AdapterService.class);
- method.setAccessible(true);
- method.invoke(null, adapterService);
+ // Hence we need to set AdapterService.sAdapterService field.
+ AdapterService.setAdapterService(adapterService);
}
/**
* Clear the return value of {@link AdapterService#getAdapterService()} to null
*
- * @param adapterService the {@link AdapterService} used when calling
- * {@link TestUtils#setAdapterService(AdapterService)}
- * @throws NoSuchMethodException when clearAdapterService method is not found
- * @throws IllegalAccessException when clearAdapterService method cannot be accessed
- * @throws InvocationTargetException when clearAdappterService method cannot be invoked,
- * which should never happen since clearAdapterService is a
- * static method
+ * @param adapterService the {@link AdapterService} used when calling {@link
+ * TestUtils#setAdapterService(AdapterService)}
*/
- public static void clearAdapterService(AdapterService adapterService)
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ public static void clearAdapterService(AdapterService adapterService) {
Assert.assertSame("AdapterService.getAdapterService() must return the same object as the"
+ " supplied adapterService in this method", adapterService,
AdapterService.getAdapterService());
Assert.assertNotNull("Adapter service should not be null", adapterService);
- Method method =
- AdapterService.class.getDeclaredMethod("clearAdapterService", AdapterService.class);
- method.setAccessible(true);
- method.invoke(null, adapterService);
+ AdapterService.clearAdapterService(adapterService);
+ }
+
+ /** Helper function to mock getSystemService calls */
+ public static <T> void mockGetSystemService(
+ Context ctx, String serviceName, Class<T> serviceClass, T mockService) {
+ when(ctx.getSystemService(eq(serviceName))).thenReturn(mockService);
+ when(ctx.getSystemServiceName(eq(serviceClass))).thenReturn(serviceName);
+ }
+
+ /** Helper function to mock getSystemService calls */
+ public static <T> T mockGetSystemService(
+ Context ctx, String serviceName, Class<T> serviceClass) {
+ T mockedService = mock(serviceClass);
+ mockGetSystemService(ctx, serviceName, serviceClass, mockedService);
+ return mockedService;
}
/**
@@ -156,6 +151,9 @@ public class TestUtils {
*/
public static <T extends ProfileService> void startService(ServiceTestRule serviceTestRule,
Class<T> profileServiceClass) throws TimeoutException {
+ if (profileServiceClass == GattService.class) {
+ Assert.assertFalse("GattService cannot be started as a service", true);
+ }
AdapterService adapterService = AdapterService.getAdapterService();
Assert.assertNotNull("Adapter service should not be null", adapterService);
Assert.assertTrue("AdapterService.getAdapterService() must return a mocked or spied object"
diff --git a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java
index 80c62f0edc..2fa6849c3e 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachineTest.java
@@ -405,7 +405,7 @@ public class AvrcpControllerStateMachineTest {
BluetoothMediaBrowserService.getTransportControls();
Assert.assertNotNull(transportControls);
Assert.assertEquals(PlaybackStateCompat.STATE_NONE,
- BluetoothMediaBrowserService.getPlaybackState());
+ BluetoothMediaBrowserService.getPlaybackState().getState());
mAvrcpStateMachine.disconnect();
numBroadcastsSent += 2;
verify(mAvrcpControllerService,
@@ -434,7 +434,7 @@ public class AvrcpControllerStateMachineTest {
int numBroadcastsSent = setUpConnectedState(false, true);
Assert.assertEquals(1, mAvrcpControllerService.sBrowseTree.mRootNode.getChildrenCount());
Assert.assertEquals(PlaybackStateCompat.STATE_NONE,
- BluetoothMediaBrowserService.getPlaybackState());
+ BluetoothMediaBrowserService.getPlaybackState().getState());
mAvrcpStateMachine.disconnect();
numBroadcastsSent += 2;
verify(mAvrcpControllerService,
@@ -1268,6 +1268,69 @@ public class AvrcpControllerStateMachineTest {
Assert.assertFalse(mAvrcpStateMachine.isActive());
}
+ @Test
+ public void testTrackChangedWhileActive_currentTrackAndQueueNumberUpdated() {
+ setUpConnectedState(true, true);
+
+ // Set track
+ AvrcpItem track = makeTrack("Song 1", "artist", "album", 1, 2, "none", 10, null);
+ setCurrentTrack(track);
+
+ // Set current Now Playing list
+ List<AvrcpItem> nowPlayingList = new ArrayList<AvrcpItem>();
+ nowPlayingList.add(makeNowPlayingItem(1, "Song 1"));
+ nowPlayingList.add(makeNowPlayingItem(2, "Song 2"));
+ setNowPlayingList(nowPlayingList);
+
+ // Set playing
+ setPlaybackState(PlaybackStateCompat.STATE_PLAYING);
+
+ // Wait
+ TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper());
+
+ // Verify track and playback state
+ MediaSessionCompat session = BluetoothMediaBrowserService.getSession();
+ Assert.assertNotNull(session);
+ MediaControllerCompat controller = session.getController();
+ Assert.assertNotNull(controller);
+
+ MediaMetadataCompat metadata = controller.getMetadata();
+ Assert.assertNotNull(metadata);
+ Assert.assertEquals("Song 1", metadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE));
+ Assert.assertEquals("artist", metadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST));
+ Assert.assertEquals("album", metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM));
+ Assert.assertEquals(1, metadata.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER));
+ Assert.assertEquals(2, metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS));
+ Assert.assertEquals("none", metadata.getString(MediaMetadataCompat.METADATA_KEY_GENRE));
+ Assert.assertEquals(10, metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION));
+
+ PlaybackStateCompat playbackState = controller.getPlaybackState();
+ Assert.assertNotNull(playbackState);
+ Assert.assertEquals(PlaybackStateCompat.STATE_PLAYING, playbackState.getState());
+ Assert.assertEquals(0, playbackState.getActiveQueueItemId());
+
+ // Track changes, with new metadata and new track number
+ track = makeTrack("Song 2", "artist", "album", 2, 2, "none", 10, null);
+ setCurrentTrack(track);
+ TestUtils.waitForLooperToFinishScheduledTask(mAvrcpStateMachine.getHandler().getLooper());
+
+ // Assert new track metadata and active queue item
+ metadata = controller.getMetadata();
+ Assert.assertNotNull(metadata);
+ Assert.assertEquals("Song 2", metadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE));
+ Assert.assertEquals("artist", metadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST));
+ Assert.assertEquals("album", metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM));
+ Assert.assertEquals(2, metadata.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER));
+ Assert.assertEquals(2, metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS));
+ Assert.assertEquals("none", metadata.getString(MediaMetadataCompat.METADATA_KEY_GENRE));
+ Assert.assertEquals(10, metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION));
+
+ playbackState = controller.getPlaybackState();
+ Assert.assertNotNull(playbackState);
+ Assert.assertEquals(PlaybackStateCompat.STATE_PLAYING, playbackState.getState());
+ Assert.assertEquals(1, playbackState.getActiveQueueItemId());
+ }
+
/**
* Test receiving a track change update when we're not the active device
*/
@@ -1318,7 +1381,7 @@ public class AvrcpControllerStateMachineTest {
eq(mTestAddress), eq(AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE), eq(KEY_DOWN));
verify(mA2dpSinkService, never()).requestAudioFocus(mTestDevice, true);
Assert.assertEquals(PlaybackStateCompat.STATE_ERROR,
- BluetoothMediaBrowserService.getPlaybackState());
+ BluetoothMediaBrowserService.getPlaybackState().getState());
}
/**
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java
index 24f282dafa..1b444ced73 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java
@@ -32,11 +32,9 @@ import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothSinkAudioPolicy;
import android.content.Context;
-import android.content.Intent;
import android.media.AudioManager;
import android.util.ArrayMap;
import android.util.SparseIntArray;
@@ -1249,11 +1247,8 @@ public class ActiveDeviceManagerTest {
private void leAudioConnected(BluetoothDevice device) {
mMostRecentDevice = device;
- Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_DISCONNECTED);
- intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
- mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent);
+ mActiveDeviceManager.leAudioConnectionStateChanged(
+ device, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED);
}
/**
@@ -1264,11 +1259,8 @@ public class ActiveDeviceManagerTest {
mMostRecentDevice = (mDeviceConnectionStack.size() > 0)
? mDeviceConnectionStack.get(mDeviceConnectionStack.size() - 1) : null;
- Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTED);
- intent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED);
- mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent);
+ mActiveDeviceManager.leAudioConnectionStateChanged(
+ device, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
}
/**
@@ -1279,9 +1271,7 @@ public class ActiveDeviceManagerTest {
mDeviceConnectionStack.add(device);
mMostRecentDevice = device;
- Intent intent = new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- mActiveDeviceManager.getBroadcastReceiver().onReceive(mContext, intent);
+ mActiveDeviceManager.leAudioActiveStateChanged(device);
}
/**
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java
index 9d81e88e5f..beb4a4554c 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceFactoryResetTest.java
@@ -36,6 +36,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.res.Resources;
+import android.hardware.display.DisplayManager;
import android.media.AudioManager;
import android.os.BatteryStatsManager;
import android.os.Binder;
@@ -91,16 +92,10 @@ public class AdapterServiceFactoryResetTest {
private @Mock android.app.Application mApplication;
private @Mock MetricsLogger mMockMetricsLogger;
- // Mocked SystemService
- private @Mock AlarmManager mMockAlarmManager;
- private @Mock AppOpsManager mMockAppOpsManager;
- private @Mock AudioManager mMockAudioManager;
- private @Mock DevicePolicyManager mMockDevicePolicyManager;
- private @Mock UserManager mMockUserManager;
-
// SystemService that are not mocked
private BluetoothManager mBluetoothManager;
private CompanionDeviceManager mCompanionDeviceManager;
+ private DisplayManager mDisplayManager;
private PowerManager mPowerManager;
private PermissionCheckerManager mPermissionCheckerManager;
private PermissionManager mPermissionManager;
@@ -131,6 +126,12 @@ public class AdapterServiceFactoryResetTest {
when(mMockContext.getSystemServiceName(eq(serviceClass))).thenReturn(serviceName);
}
+ <T> T mockGetSystemService(String serviceName, Class<T> serviceClass) {
+ T mockedService = mock(serviceClass);
+ mockGetSystemService(serviceName, serviceClass, mockedService);
+ return mockedService;
+ }
+
@Before
public void setUp() throws PackageManager.NameNotFoundException {
Log.e(TAG, "setUp()");
@@ -156,23 +157,20 @@ public class AdapterServiceFactoryResetTest {
}
});
- mPowerManager = InstrumentationRegistry.getTargetContext()
- .getSystemService(PowerManager.class);
- mPermissionCheckerManager = InstrumentationRegistry.getTargetContext()
- .getSystemService(PermissionCheckerManager.class);
-
- mPermissionManager = InstrumentationRegistry.getTargetContext()
- .getSystemService(PermissionManager.class);
+ Context targetContext = InstrumentationRegistry.getTargetContext();
- mBluetoothManager = InstrumentationRegistry.getTargetContext()
- .getSystemService(BluetoothManager.class);
-
- mCompanionDeviceManager =
- InstrumentationRegistry.getTargetContext()
- .getSystemService(CompanionDeviceManager.class);
+ mBluetoothManager = targetContext.getSystemService(BluetoothManager.class);
+ mCompanionDeviceManager = targetContext.getSystemService(CompanionDeviceManager.class);
+ mDisplayManager = targetContext.getSystemService(DisplayManager.class);
+ mPermissionCheckerManager = targetContext.getSystemService(PermissionCheckerManager.class);
+ mPermissionManager = targetContext.getSystemService(PermissionManager.class);
+ mPowerManager = targetContext.getSystemService(PowerManager.class);
when(mMockContext.getCacheDir())
.thenReturn(InstrumentationRegistry.getTargetContext().getCacheDir());
+ when(mMockContext.getUser())
+ .thenReturn(InstrumentationRegistry.getTargetContext().getUser());
+ when(mMockContext.getPackageName()).thenReturn("com.android.bluetooth");
when(mMockContext.getApplicationInfo()).thenReturn(mMockApplicationInfo);
when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
when(mMockContext.getApplicationContext()).thenReturn(mMockContext);
@@ -182,12 +180,13 @@ public class AdapterServiceFactoryResetTest {
when(mMockContext.getUserId()).thenReturn(Process.BLUETOOTH_UID);
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
- mockGetSystemService(Context.ALARM_SERVICE, AlarmManager.class, mMockAlarmManager);
- mockGetSystemService(Context.APP_OPS_SERVICE, AppOpsManager.class, mMockAppOpsManager);
- mockGetSystemService(Context.AUDIO_SERVICE, AudioManager.class, mMockAudioManager);
- mockGetSystemService(
- Context.DEVICE_POLICY_SERVICE, DevicePolicyManager.class, mMockDevicePolicyManager);
- mockGetSystemService(Context.USER_SERVICE, UserManager.class, mMockUserManager);
+ mockGetSystemService(Context.ALARM_SERVICE, AlarmManager.class);
+ mockGetSystemService(Context.APP_OPS_SERVICE, AppOpsManager.class);
+ mockGetSystemService(Context.AUDIO_SERVICE, AudioManager.class);
+ DevicePolicyManager dpm =
+ mockGetSystemService(Context.DEVICE_POLICY_SERVICE, DevicePolicyManager.class);
+ doReturn(false).when(dpm).isCommonCriteriaModeEnabled(any());
+ mockGetSystemService(Context.USER_SERVICE, UserManager.class);
mockGetSystemService(
Context.BATTERY_STATS_SERVICE, BatteryStatsManager.class, mBatteryStatsManager);
@@ -196,6 +195,7 @@ public class AdapterServiceFactoryResetTest {
Context.COMPANION_DEVICE_SERVICE,
CompanionDeviceManager.class,
mCompanionDeviceManager);
+ mockGetSystemService(Context.DISPLAY_SERVICE, DisplayManager.class, mDisplayManager);
mockGetSystemService(
Context.PERMISSION_CHECKER_SERVICE,
PermissionCheckerManager.class,
@@ -221,8 +221,6 @@ public class AdapterServiceFactoryResetTest {
UserHandle callingUser = UserHandle.getUserHandleForUid(callingUid);
Utils.setForegroundUserId(callingUser.getIdentifier());
- when(mMockDevicePolicyManager.isCommonCriteriaModeEnabled(any())).thenReturn(false);
-
when(mIBluetoothCallback.asBinder()).thenReturn(mBinder);
doReturn(Process.BLUETOOTH_UID).when(mMockPackageManager)
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java
index 96ccb11add..e02a34d8d4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceRestartTest.java
@@ -162,6 +162,9 @@ public class AdapterServiceRestartTest {
when(mMockContext.getCacheDir()).thenReturn(InstrumentationRegistry.getTargetContext()
.getCacheDir());
+ when(mMockContext.getUser())
+ .thenReturn(InstrumentationRegistry.getTargetContext().getUser());
+ when(mMockContext.getPackageName()).thenReturn("com.android.bluetooth");
when(mMockContext.getApplicationInfo()).thenReturn(mMockApplicationInfo);
when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
when(mMockContext.getApplicationContext()).thenReturn(mMockContext);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java
index 61aefd7b9f..db52e36d63 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java
@@ -26,6 +26,7 @@ import static android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF;
import static android.bluetooth.BluetoothAdapter.STATE_TURNING_ON;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
@@ -43,6 +44,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.content.res.Resources;
+import android.hardware.display.DisplayManager;
import android.media.AudioManager;
import android.os.BatteryStatsManager;
import android.os.Binder;
@@ -142,16 +144,10 @@ public class AdapterServiceTest {
private @Mock android.app.Application mApplication;
private @Mock MetricsLogger mMockMetricsLogger;
- // Mocked SystemService
- private @Mock AlarmManager mMockAlarmManager;
- private @Mock AppOpsManager mMockAppOpsManager;
- private @Mock AudioManager mMockAudioManager;
- private @Mock DevicePolicyManager mMockDevicePolicyManager;
- private @Mock UserManager mMockUserManager;
-
// SystemService that are not mocked
private BluetoothManager mBluetoothManager;
private CompanionDeviceManager mCompanionDeviceManager;
+ private DisplayManager mDisplayManager;
private PowerManager mPowerManager;
private PermissionCheckerManager mPermissionCheckerManager;
private PermissionManager mPermissionManager;
@@ -222,8 +218,11 @@ public class AdapterServiceTest {
}
<T> void mockGetSystemService(String serviceName, Class<T> serviceClass, T mockService) {
- when(mMockContext.getSystemService(eq(serviceName))).thenReturn(mockService);
- when(mMockContext.getSystemServiceName(eq(serviceClass))).thenReturn(serviceName);
+ TestUtils.mockGetSystemService(mMockContext, serviceName, serviceClass, mockService);
+ }
+
+ <T> T mockGetSystemService(String serviceName, Class<T> serviceClass) {
+ return TestUtils.mockGetSystemService(mMockContext, serviceName, serviceClass);
}
@Before
@@ -251,23 +250,20 @@ public class AdapterServiceTest {
}
});
- mPowerManager = InstrumentationRegistry.getTargetContext()
- .getSystemService(PowerManager.class);
- mPermissionCheckerManager = InstrumentationRegistry.getTargetContext()
- .getSystemService(PermissionCheckerManager.class);
-
- mPermissionManager = InstrumentationRegistry.getTargetContext()
- .getSystemService(PermissionManager.class);
+ Context targetContext = InstrumentationRegistry.getTargetContext();
- mBluetoothManager = InstrumentationRegistry.getTargetContext()
- .getSystemService(BluetoothManager.class);
-
- mCompanionDeviceManager =
- InstrumentationRegistry.getTargetContext()
- .getSystemService(CompanionDeviceManager.class);
+ mBluetoothManager = targetContext.getSystemService(BluetoothManager.class);
+ mCompanionDeviceManager = targetContext.getSystemService(CompanionDeviceManager.class);
+ mDisplayManager = targetContext.getSystemService(DisplayManager.class);
+ mPermissionCheckerManager = targetContext.getSystemService(PermissionCheckerManager.class);
+ mPermissionManager = targetContext.getSystemService(PermissionManager.class);
+ mPowerManager = targetContext.getSystemService(PowerManager.class);
when(mMockContext.getCacheDir()).thenReturn(InstrumentationRegistry.getTargetContext()
.getCacheDir());
+ when(mMockContext.getUser())
+ .thenReturn(InstrumentationRegistry.getTargetContext().getUser());
+ when(mMockContext.getPackageName()).thenReturn("com.android.bluetooth");
when(mMockContext.getApplicationInfo()).thenReturn(mMockApplicationInfo);
when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
when(mMockContext.getApplicationContext()).thenReturn(mMockContext);
@@ -277,12 +273,13 @@ public class AdapterServiceTest {
when(mMockContext.getUserId()).thenReturn(Process.BLUETOOTH_UID);
when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
- mockGetSystemService(Context.ALARM_SERVICE, AlarmManager.class, mMockAlarmManager);
- mockGetSystemService(Context.APP_OPS_SERVICE, AppOpsManager.class, mMockAppOpsManager);
- mockGetSystemService(Context.AUDIO_SERVICE, AudioManager.class, mMockAudioManager);
- mockGetSystemService(
- Context.DEVICE_POLICY_SERVICE, DevicePolicyManager.class, mMockDevicePolicyManager);
- mockGetSystemService(Context.USER_SERVICE, UserManager.class, mMockUserManager);
+ mockGetSystemService(Context.ALARM_SERVICE, AlarmManager.class);
+ mockGetSystemService(Context.APP_OPS_SERVICE, AppOpsManager.class);
+ mockGetSystemService(Context.AUDIO_SERVICE, AudioManager.class);
+ DevicePolicyManager dpm =
+ mockGetSystemService(Context.DEVICE_POLICY_SERVICE, DevicePolicyManager.class);
+ doReturn(false).when(dpm).isCommonCriteriaModeEnabled(any());
+ mockGetSystemService(Context.USER_SERVICE, UserManager.class);
mockGetSystemService(
Context.BATTERY_STATS_SERVICE, BatteryStatsManager.class, mBatteryStatsManager);
@@ -291,6 +288,7 @@ public class AdapterServiceTest {
Context.COMPANION_DEVICE_SERVICE,
CompanionDeviceManager.class,
mCompanionDeviceManager);
+ mockGetSystemService(Context.DISPLAY_SERVICE, DisplayManager.class, mDisplayManager);
mockGetSystemService(
Context.PERMISSION_CHECKER_SERVICE,
PermissionCheckerManager.class,
@@ -303,8 +301,6 @@ public class AdapterServiceTest {
.thenReturn(InstrumentationRegistry.getTargetContext()
.getSharedPreferences("AdapterServiceTestPrefs", Context.MODE_PRIVATE));
- doReturn(true).when(mMockContext).bindServiceAsUser(any(), any(), anyInt(), any());
-
doAnswer(invocation -> {
Object[] args = invocation.getArguments();
return InstrumentationRegistry.getTargetContext().getDatabasePath((String) args[0]);
@@ -316,8 +312,6 @@ public class AdapterServiceTest {
UserHandle callingUser = UserHandle.getUserHandleForUid(callingUid);
Utils.setForegroundUserId(callingUser.getIdentifier());
- when(mMockDevicePolicyManager.isCommonCriteriaModeEnabled(any())).thenReturn(false);
-
when(mIBluetoothCallback.asBinder()).thenReturn(mBinder);
doReturn(Process.BLUETOOTH_UID).when(mMockPackageManager)
@@ -367,14 +361,23 @@ public class AdapterServiceTest {
syncHandler(mLooper, what);
}
+ private void dropNextMessage(int what) {
+ Message msg = mLooper.nextMessage();
+ assertThat(msg).isNotNull();
+ assertWithMessage("Not the expected Message:\n" + msg).that(msg.what).isEqualTo(what);
+ Log.d(TAG, "Message dropped on purpose: " + msg);
+ }
+
private static void syncHandler(TestLooper looper, int... what) {
IntStream.of(what)
.forEach(
w -> {
Message msg = looper.nextMessage();
assertThat(msg).isNotNull();
- assertThat(msg.what).isEqualTo(w);
- Log.d(TAG, "Processing message: " + msg.what);
+ assertWithMessage("Not the expected Message:\n" + msg)
+ .that(msg.what)
+ .isEqualTo(w);
+ Log.d(TAG, "Processing message: " + msg);
msg.getTarget().dispatchMessage(msg);
});
}
@@ -422,12 +425,9 @@ public class AdapterServiceTest {
adapter.enable(false);
syncHandler(looper, AdapterState.BLE_TURN_ON);
verifyStateChange(callback, STATE_OFF, STATE_BLE_TURNING_ON);
- verify(ctx).bindServiceAsUser(any(), any(), anyInt(), any());
- adapter.addProfile(gattService);
syncHandler(looper, MESSAGE_PROFILE_SERVICE_REGISTERED);
- adapter.onProfileServiceStateChanged(gattService, STATE_ON);
syncHandler(looper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
// Native loop is not in TestLooper and it will send a event later
@@ -550,9 +550,7 @@ public class AdapterServiceTest {
adapter.stopBle();
syncHandler(looper, AdapterState.BLE_TURN_OFF);
verifyStateChange(callback, STATE_BLE_ON, STATE_BLE_TURNING_OFF);
- verify(ctx).unbindService(any());
- adapter.onProfileServiceStateChanged(gattService, STATE_OFF);
syncHandler(looper, MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
// Native loop is not in TestLooper and it will send a event later
@@ -630,14 +628,15 @@ public class AdapterServiceTest {
mAdapterService.enable(false);
syncHandler(AdapterState.BLE_TURN_ON);
verifyStateChange(STATE_OFF, STATE_BLE_TURNING_ON);
- verify(mMockContext).bindServiceAsUser(any(), any(), anyInt(), any());
-
- mAdapterService.addProfile(mMockGattService);
+ assertThat(mAdapterService.getBluetoothGatt()).isNotNull();
syncHandler(MESSAGE_PROFILE_SERVICE_REGISTERED);
+ // Fetch next message and never process it to simulate a timeout.
+ dropNextMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
+
mLooper.moveTimeForward(120_000); // Skip time so the timeout fires
syncHandler(AdapterState.BLE_START_TIMEOUT);
- verify(mMockContext).unbindService(any());
+ assertThat(mAdapterService.getBluetoothGatt()).isNull();
// Native loop is not in TestLooper and it will send a event later
mLooper.startAutoDispatch();
@@ -666,7 +665,11 @@ public class AdapterServiceTest {
mAdapterService.stopBle();
syncHandler(AdapterState.BLE_TURN_OFF);
verifyStateChange(STATE_BLE_ON, STATE_BLE_TURNING_OFF, CONTEXT_SWITCH_MS);
- verify(mMockContext).unbindService(any()); // Stop GATT
+ assertThat(mAdapterService.getBluetoothGatt()).isNull();
+
+ // Fetch Gatt message and never process it to simulate a timeout.
+ dropNextMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
+ dropNextMessage(MESSAGE_PROFILE_SERVICE_UNREGISTERED);
mLooper.moveTimeForward(120_000); // Skip time so the timeout fires
syncHandler(AdapterState.BLE_STOP_TIMEOUT);
@@ -711,7 +714,7 @@ public class AdapterServiceTest {
verifyStateChange(STATE_TURNING_OFF, STATE_BLE_ON);
// Ensure GATT is still running
- verify(mMockContext, times(0)).unbindService(any());
+ assertThat(mAdapterService.getBluetoothGatt()).isNotNull();
}
/**
@@ -735,10 +738,9 @@ public class AdapterServiceTest {
mLooper.moveTimeForward(120_000); // Skip time so the timeout fires
syncHandler(AdapterState.BREDR_STOP_TIMEOUT);
verifyStateChange(STATE_TURNING_OFF, STATE_BLE_TURNING_OFF);
- verify(mMockContext).unbindService(any());
- mAdapterService.onProfileServiceStateChanged(mMockGattService, STATE_OFF);
syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
+ syncHandler(MESSAGE_PROFILE_SERVICE_UNREGISTERED);
// TODO(b/280518177): The only timeout to fire here should be the BREDR
mLooper.moveTimeForward(120_000); // Skip time so the timeout fires
@@ -778,10 +780,7 @@ public class AdapterServiceTest {
// Do not call stopBle(). The Adapter should turn itself off.
syncHandler(AdapterState.BLE_TURN_OFF);
verifyStateChange(STATE_BLE_ON, STATE_BLE_TURNING_OFF, CONTEXT_SWITCH_MS);
- verify(mMockContext).unbindService(any()); // stop Gatt
-
- mAdapterService.onProfileServiceStateChanged(mMockGattService, STATE_OFF);
- syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
+ syncHandler(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); // stop GATT
// Native loop is not in TestLooper and it will send a event later
mLooper.startAutoDispatch();
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/ConfigTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/ConfigTest.java
new file mode 100644
index 0000000000..7b97035ed5
--- /dev/null
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/ConfigTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+package com.android.bluetooth.btservice;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.bluetooth.csip.CsipSetCoordinatorService;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Arrays;
+
+@RunWith(JUnit4.class)
+public final class ConfigTest {
+ @Test
+ public void setProfileEnabled() {
+ boolean enabled =
+ Arrays.stream(Config.getSupportedProfiles())
+ .anyMatch(cls -> cls == CsipSetCoordinatorService.class);
+
+ Config.setProfileEnabled(CsipSetCoordinatorService.class, false);
+ assertThat(
+ Arrays.stream(Config.getSupportedProfiles())
+ .anyMatch(cls -> cls == CsipSetCoordinatorService.class))
+ .isFalse();
+
+ Config.setProfileEnabled(CsipSetCoordinatorService.class, true);
+ assertThat(
+ Arrays.stream(Config.getSupportedProfiles())
+ .anyMatch(cls -> cls == CsipSetCoordinatorService.class))
+ .isTrue();
+
+ Config.setProfileEnabled(CsipSetCoordinatorService.class, enabled);
+ }
+}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java
index 4cc055e35d..15721bb004 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/ProfileServiceTest.java
@@ -16,6 +16,10 @@
package com.android.bluetooth.btservice;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
@@ -32,6 +36,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.storage.DatabaseManager;
+import com.android.bluetooth.gatt.GattService;
import org.junit.After;
import org.junit.Assert;
@@ -78,7 +83,13 @@ public class ProfileServiceTest {
}
private void setAllProfilesState(int state, int invocationNumber) throws TimeoutException {
+ int profileCount = mProfiles.length;
for (Class profile : mProfiles) {
+ if (profile == GattService.class) {
+ // GattService is no longer a service to be start independently
+ profileCount--;
+ continue;
+ }
setProfileState(profile, state);
}
if (invocationNumber == 0) {
@@ -87,11 +98,15 @@ public class ProfileServiceTest {
return;
}
ArgumentCaptor<ProfileService> argument = ArgumentCaptor.forClass(ProfileService.class);
- verify(mMockAdapterService, timeout(PROFILE_START_MILLIS).times(
- mProfiles.length * invocationNumber)).onProfileServiceStateChanged(
- argument.capture(), eq(state));
+ verify(
+ mMockAdapterService,
+ timeout(PROFILE_START_MILLIS).times(profileCount * invocationNumber))
+ .onProfileServiceStateChanged(argument.capture(), eq(state));
List<ProfileService> argumentProfiles = argument.getAllValues();
for (Class profile : mProfiles) {
+ if (profile == GattService.class) {
+ continue;
+ }
int matches = 0;
for (ProfileService arg : argumentProfiles) {
if (arg.getClass().getName().equals(profile.getName())) {
@@ -118,27 +133,41 @@ public class ProfileServiceTest {
return mStartedProfileMap.get((String) args[0]);
}
});
+ doReturn(mDatabaseManager).when(mMockAdapterService).getDatabase();
+
when(mMockAdapterService.getSystemService(Context.LOCATION_SERVICE))
.thenReturn(mLocationManager);
when(mMockAdapterService.getSystemServiceName(LocationManager.class))
.thenReturn(Context.LOCATION_SERVICE);
+ // Despite calling on the Mock of adapterService, mockito cannot handle native method and
+ // will call the real method instead, allowing to initialize the native library
+ // when(mMockAdapterService.initNative(anyBoolean(), anyBoolean(), anyInt(), any(),
+ // anyBoolean(), anyString())).thenCallRealMethod();
+ doCallRealMethod()
+ .when(mMockAdapterService)
+ .initNative(anyBoolean(), anyBoolean(), anyInt(), any(), anyBoolean(), anyString());
+ doCallRealMethod().when(mMockAdapterService).enableNative();
+ doCallRealMethod().when(mMockAdapterService).disableNative();
+ doCallRealMethod().when(mMockAdapterService).cleanupNative();
+
mProfiles = Config.getSupportedProfiles();
+ TestUtils.setAdapterService(mMockAdapterService);
+
+ Assert.assertNotNull(AdapterService.getAdapterService());
mMockAdapterService.initNative(false /* is_restricted */,
false /* is_common_criteria_mode */, 0 /* config_compare_result */,
new String[0], false, "");
-
- TestUtils.setAdapterService(mMockAdapterService);
- doReturn(mDatabaseManager).when(mMockAdapterService).getDatabase();
-
- Assert.assertNotNull(AdapterService.getAdapterService());
+ mMockAdapterService.enableNative();
}
@After
public void tearDown()
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+ mMockAdapterService.disableNative();
mMockAdapterService.cleanupNative();
+
TestUtils.clearAdapterService(mMockAdapterService);
mMockAdapterService = null;
mProfiles = null;
@@ -172,13 +201,18 @@ public class ProfileServiceTest {
*/
@Test
public void testEnableDisableInterleaved() throws TimeoutException {
+ int invocationNumber = mProfiles.length;
for (Class profile : mProfiles) {
+ if (profile == GattService.class) {
+ // GattService is no longer a service to be start independently
+ invocationNumber--;
+ continue;
+ }
setProfileState(profile, BluetoothAdapter.STATE_ON);
setProfileState(profile, BluetoothAdapter.STATE_OFF);
}
ArgumentCaptor<ProfileService> starts = ArgumentCaptor.forClass(ProfileService.class);
ArgumentCaptor<ProfileService> stops = ArgumentCaptor.forClass(ProfileService.class);
- int invocationNumber = mProfiles.length;
verify(mMockAdapterService,
timeout(PROFILE_START_MILLIS).times(invocationNumber)).onProfileServiceStateChanged(
starts.capture(), eq(BluetoothAdapter.STATE_ON));
@@ -204,6 +238,10 @@ public class ProfileServiceTest {
public void testRepeatedEnableDisableSingly() throws TimeoutException {
int profileNumber = 0;
for (Class profile : mProfiles) {
+ if (profile == GattService.class) {
+ // GattService is no longer a service to be start independently
+ continue;
+ }
for (int i = 0; i < NUM_REPEATS; i++) {
setProfileState(profile, BluetoothAdapter.STATE_ON);
ArgumentCaptor<ProfileService> start =
@@ -230,6 +268,10 @@ public class ProfileServiceTest {
public void testProfileServiceRegisterUnregister() throws TimeoutException {
int profileNumber = 0;
for (Class profile : mProfiles) {
+ if (profile == GattService.class) {
+ // GattService is no longer a service to be start independently
+ continue;
+ }
for (int i = 0; i < NUM_REPEATS; i++) {
setProfileState(profile, BluetoothAdapter.STATE_ON);
ArgumentCaptor<ProfileService> start =
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionServiceTest.java
index 7f845b5dc8..8a4db9a7a4 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/activityAttribution/ActivityAttributionServiceTest.java
@@ -16,12 +16,9 @@
package com.android.bluetooth.btservice.activityattribution;
-import static com.google.common.truth.Truth.assertThat;
-
import android.os.Binder;
import android.os.Process;
-import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
@@ -30,24 +27,12 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public final class ActivityAttributionServiceTest {
- private static final String TAG = "ActivityAttributionServiceTest";
private ActivityAttributionService mActivityAttributionService;
@Before
public void setUp() {
Assume.assumeTrue("Ignore test when the user is not primary.", isPrimaryUser());
mActivityAttributionService = new ActivityAttributionService();
- mActivityAttributionService.start();
- assertThat(mActivityAttributionService).isNotNull();
- }
-
- @After
- public void tearDown() {
- if (!isPrimaryUser()) {
- return;
- }
- mActivityAttributionService.cleanup();
- mActivityAttributionService = null;
}
private boolean isPrimaryUser() {
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/gatt/AdvertiseManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java
index 74d0e64365..c7bf403325 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/AdvertiseManagerTest.java
@@ -16,7 +16,6 @@
package com.android.bluetooth.gatt;
-import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@@ -59,6 +58,8 @@ public class AdvertiseManagerTest {
@Mock
private GattService.AdvertiserMap mAdvertiserMap;
+ @Mock private AdvertiseManagerNativeInterface mNativeInterface;
+
@Mock
private IAdvertisingSetCallback mCallback;
@@ -74,7 +75,9 @@ public class AdvertiseManagerTest {
TestUtils.setAdapterService(mAdapterService);
- mAdvertiseManager = new AdvertiseManager(mService, mAdapterService, mAdvertiserMap);
+ mAdvertiseManager =
+ new AdvertiseManager(mService, mNativeInterface, mAdapterService, mAdvertiserMap);
+
AdvertisingSetParameters parameters = new AdvertisingSetParameters.Builder().build();
AdvertiseData advertiseData = new AdvertiseData.Builder().build();
AdvertiseData scanResponse = new AdvertiseData.Builder().build();
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/AppScanStatsTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/AppScanStatsTest.java
index 359ad3104e..b1bed3da63 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/gatt/AppScanStatsTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/AppScanStatsTest.java
@@ -18,9 +18,6 @@ package com.android.bluetooth.gatt;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.when;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
@@ -28,6 +25,7 @@ import android.content.Context;
import android.location.LocationManager;
import android.os.WorkSource;
+import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.rule.ServiceTestRule;
import androidx.test.runner.AndroidJUnit4;
@@ -64,28 +62,23 @@ public class AppScanStatsTest {
@Mock
private AdapterService mAdapterService;
- @Mock private LocationManager mLocationManager;
-
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
- doReturn(true).when(mAdapterService).isStartedProfile(anyString());
- when(mAdapterService.getSystemService(Context.LOCATION_SERVICE))
- .thenReturn(mLocationManager);
- when(mAdapterService.getSystemServiceName(LocationManager.class))
- .thenReturn(Context.LOCATION_SERVICE);
-
- TestUtils.startService(mServiceRule, GattService.class);
- mService = GattService.getGattService();
+
+ TestUtils.mockGetSystemService(
+ mAdapterService, Context.LOCATION_SERVICE, LocationManager.class);
+
+ mService = new GattService(InstrumentationRegistry.getTargetContext());
+ mService.start();
}
@After
public void tearDown() throws Exception {
- doReturn(false).when(mAdapterService).isStartedProfile(anyString());
- TestUtils.stopService(mServiceRule, GattService.class);
- mService = GattService.getGattService();
+ mService.stop();
+ mService = null;
TestUtils.clearAdapterService(mAdapterService);
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java
index 3ff84eea8d..e391a38c95 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/ContextMapTest.java
@@ -18,10 +18,8 @@ package com.android.bluetooth.gatt;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertisingSetParameters;
@@ -30,6 +28,7 @@ import android.content.Context;
import android.location.LocationManager;
import android.os.Binder;
+import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.rule.ServiceTestRule;
import androidx.test.runner.AndroidJUnit4;
@@ -64,8 +63,6 @@ public class ContextMapTest {
@Mock
private AdapterService mAdapterService;
- @Mock private LocationManager mLocationManager;
-
@Mock
private AppAdvertiseStats appAdvertiseStats;
@@ -78,23 +75,20 @@ public class ContextMapTest {
BluetoothMethodProxy.setInstanceForTesting(mMapMethodProxy);
TestUtils.setAdapterService(mAdapterService);
- doReturn(true).when(mAdapterService).isStartedProfile(anyString());
- when(mAdapterService.getSystemService(Context.LOCATION_SERVICE))
- .thenReturn(mLocationManager);
- when(mAdapterService.getSystemServiceName(LocationManager.class))
- .thenReturn(Context.LOCATION_SERVICE);
-
- TestUtils.startService(mServiceRule, GattService.class);
- mService = GattService.getGattService();
+
+ TestUtils.mockGetSystemService(
+ mAdapterService, Context.LOCATION_SERVICE, LocationManager.class);
+
+ mService = new GattService(InstrumentationRegistry.getTargetContext());
+ mService.start();
}
@After
public void tearDown() throws Exception {
BluetoothMethodProxy.setInstanceForTesting(null);
- doReturn(false).when(mAdapterService).isStartedProfile(anyString());
- TestUtils.stopService(mServiceRule, GattService.class);
- mService = GattService.getGattService();
+ mService.stop();
+ mService = null;
TestUtils.clearAdapterService(mAdapterService);
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java
index 714e911a41..1c1fda0007 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceBinderTest.java
@@ -756,13 +756,6 @@ public class GattServiceBinderTest {
}
@Test
- public void unregAll() throws Exception {
- mBinder.unregAll(mAttributionSource);
-
- verify(mService).unregAll(mAttributionSource);
- }
-
- @Test
public void numHwTrackFiltersAvailable() throws Exception {
mBinder.numHwTrackFiltersAvailable(mAttributionSource, SynchronousResultReceiver.get());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java
index bf3c8364a9..6d092c0787 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java
@@ -25,21 +25,17 @@ import static org.mockito.Mockito.verify;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
-import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothStatusCodes;
import android.bluetooth.IBluetoothGattCallback;
-import android.bluetooth.IBluetoothGattServerCallback;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertisingSetParameters;
import android.bluetooth.le.DistanceMeasurementMethod;
import android.bluetooth.le.DistanceMeasurementParams;
-import android.bluetooth.le.IAdvertisingSetCallback;
import android.bluetooth.le.IDistanceMeasurementCallback;
import android.bluetooth.le.IPeriodicAdvertisingCallback;
import android.bluetooth.le.IScannerCallback;
import android.bluetooth.le.PeriodicAdvertisingParameters;
-import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.AttributionSource;
@@ -47,7 +43,6 @@ import android.content.Context;
import android.content.res.Resources;
import android.location.LocationManager;
import android.os.Binder;
-import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.WorkSource;
@@ -56,14 +51,12 @@ import androidx.test.filters.SmallTest;
import androidx.test.rule.ServiceTestRule;
import androidx.test.runner.AndroidJUnit4;
-import com.android.bluetooth.R;
import com.android.bluetooth.TestUtils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.CompanionManager;
import org.junit.After;
import org.junit.Assert;
-import org.junit.Assume;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
@@ -102,7 +95,6 @@ public class GattServiceTest {
@Mock private Set<String> mReliableQueue;
@Mock private GattService.ServerMap mServerMap;
@Mock private DistanceMeasurementManager mDistanceMeasurementManager;
- @Mock private LocationManager mLocationManager;
@Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();
@@ -123,7 +115,6 @@ public class GattServiceTest {
MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
- doReturn(true).when(mAdapterService).isStartedProfile(anyString());
GattObjectsFactory.setInstanceForTesting(mFactory);
doReturn(mNativeInterface).when(mFactory).getNativeInterface();
@@ -141,17 +132,15 @@ public class GattServiceTest {
when(mAdapterService.getSharedPreferences(anyString(), anyInt()))
.thenReturn(InstrumentationRegistry.getTargetContext()
.getSharedPreferences("GattServiceTestPrefs", Context.MODE_PRIVATE));
- when(mAdapterService.getSystemService(Context.LOCATION_SERVICE))
- .thenReturn(mLocationManager);
- when(mAdapterService.getSystemServiceName(LocationManager.class))
- .thenReturn(Context.LOCATION_SERVICE);
+
+ TestUtils.mockGetSystemService(
+ mAdapterService, Context.LOCATION_SERVICE, LocationManager.class);
mBtCompanionManager = new CompanionManager(mAdapterService, null);
doReturn(mBtCompanionManager).when(mAdapterService).getCompanionManager();
- TestUtils.startService(mServiceRule, GattService.class);
- mService = GattService.getGattService();
- Assert.assertNotNull(mService);
+ mService = new GattService(InstrumentationRegistry.getTargetContext());
+ mService.start();
mService.mClientMap = mClientMap;
mService.mScannerMap = mScannerMap;
@@ -161,40 +150,25 @@ public class GattServiceTest {
@After
public void tearDown() throws Exception {
- doReturn(false).when(mAdapterService).isStartedProfile(anyString());
- TestUtils.stopService(mServiceRule, GattService.class);
- mService = GattService.getGattService();
- Assert.assertNull(mService);
+ mService.stop();
+ mService = null;
+
TestUtils.clearAdapterService(mAdapterService);
GattObjectsFactory.setInstanceForTesting(null);
}
@Test
- public void testInitialize() {
- Assert.assertEquals(mService, GattService.getGattService());
- verify(mNativeInterface).init(eq(mService));
- }
-
- @Test
public void testServiceUpAndDown() throws Exception {
for (int i = 0; i < TIMES_UP_AND_DOWN; i++) {
- GattService gattService = GattService.getGattService();
- doReturn(false).when(mAdapterService).isStartedProfile(anyString());
- TestUtils.stopService(mServiceRule, GattService.class);
- mService = GattService.getGattService();
- Assert.assertNull(mService);
- gattService.cleanup();
+ mService.stop();
+ mService = null;
+
TestUtils.clearAdapterService(mAdapterService);
reset(mAdapterService);
TestUtils.setAdapterService(mAdapterService);
- doReturn(true).when(mAdapterService).isStartedProfile(anyString());
- when(mAdapterService.getSystemService(Context.LOCATION_SERVICE))
- .thenReturn(mLocationManager);
- when(mAdapterService.getSystemServiceName(LocationManager.class))
- .thenReturn(Context.LOCATION_SERVICE);
- TestUtils.startService(mServiceRule, GattService.class);
- mService = GattService.getGattService();
- Assert.assertNotNull(mService);
+
+ mService = new GattService(InstrumentationRegistry.getTargetContext());
+ mService.start();
}
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/ScanManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/ScanManagerTest.java
index 9f6961e206..42d26f77b0 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/gatt/ScanManagerTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/ScanManagerTest.java
@@ -29,7 +29,6 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.doReturn;
@@ -118,17 +117,15 @@ public class ScanManagerTest {
MockitoAnnotations.initMocks(this);
TestUtils.setAdapterService(mAdapterService);
- doReturn(true).when(mAdapterService).isStartedProfile(anyString());
when(mAdapterService.getScanTimeoutMillis()).
thenReturn((long) DELAY_DEFAULT_SCAN_TIMEOUT_MS);
when(mAdapterService.getNumOfOffloadedScanFilterSupported())
.thenReturn(DEFAULT_NUM_OFFLOAD_SCAN_FILTER);
when(mAdapterService.getOffloadedScanResultStorage())
.thenReturn(DEFAULT_BYTES_OFFLOAD_SCAN_RESULT_STORAGE);
- when(mAdapterService.getSystemService(Context.LOCATION_SERVICE))
- .thenReturn(mLocationManager);
- when(mAdapterService.getSystemServiceName(LocationManager.class))
- .thenReturn(Context.LOCATION_SERVICE);
+
+ TestUtils.mockGetSystemService(
+ mAdapterService, Context.LOCATION_SERVICE, LocationManager.class, mLocationManager);
doReturn(true).when(mLocationManager).isLocationEnabled();
BluetoothAdapterProxy.setInstanceForTesting(mBluetoothAdapterProxy);
@@ -143,9 +140,8 @@ public class ScanManagerTest {
MetricsLogger.setInstanceForTesting(mMetricsLogger);
- TestUtils.startService(mServiceRule, GattService.class);
- mService = GattService.getGattService();
- assertThat(mService).isNotNull();
+ mService = new GattService(InstrumentationRegistry.getTargetContext());
+ mService.start();
mScanManager = mService.getScanManager();
assertThat(mScanManager).isNotNull();
@@ -161,10 +157,9 @@ public class ScanManagerTest {
@After
public void tearDown() throws Exception {
- doReturn(false).when(mAdapterService).isStartedProfile(anyString());
- TestUtils.stopService(mServiceRule, GattService.class);
- mService = GattService.getGattService();
- assertThat(mService).isNull();
+ mService.stop();
+ mService = null;
+
TestUtils.clearAdapterService(mAdapterService);
BluetoothAdapterProxy.setInstanceForTesting(null);
GattObjectsFactory.setInstanceForTesting(null);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java
index 008fc0d349..b689546d9b 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java
@@ -56,6 +56,7 @@ import androidx.test.rule.ServiceTestRule;
import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.TestUtils;
+import com.android.bluetooth.btservice.ActiveDeviceManager;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ServiceFactory;
import com.android.bluetooth.btservice.storage.DatabaseManager;
@@ -109,6 +110,7 @@ public class LeAudioServiceTest {
private BroadcastReceiver mLeAudioIntentReceiver;
@Mock private AdapterService mAdapterService;
+ @Mock private ActiveDeviceManager mActiveDeviceManager;
@Mock private AudioManager mAudioManager;
@Mock private DatabaseManager mDatabaseManager;
@Mock private LeAudioNativeInterface mNativeInterface;
@@ -169,6 +171,7 @@ public class LeAudioServiceTest {
doReturn(MAX_LE_AUDIO_CONNECTIONS).when(mAdapterService).getMaxConnectedAudioDevices();
doReturn(new ParcelUuid[]{BluetoothUuid.LE_AUDIO}).when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
+ doReturn(mActiveDeviceManager).when(mAdapterService).getActiveDeviceManager();
doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
doReturn(true, false).when(mAdapterService).isStartedProfile(anyString());
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java
index e75f2fda45..ac69b84dfa 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioStateMachineTest.java
@@ -17,15 +17,17 @@
package com.android.bluetooth.le_audio;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.after;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
-import static com.google.common.truth.Truth.assertThat;
-
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
@@ -45,7 +47,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -146,12 +147,10 @@ public class LeAudioStateMachineTest {
connStCh.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_CONNECTING;
mLeAudioStateMachine.sendMessage(LeAudioStateMachine.STACK_EVENT, connStCh);
- // Verify that one connection state broadcast is executed
- ArgumentCaptor<Intent> intentArgument1 = ArgumentCaptor.forClass(Intent.class);
- verify(mLeAudioService, timeout(TIMEOUT_MS).times(1)).sendBroadcast(
- intentArgument1.capture(), anyString(), any(Bundle.class));
- assertThat(BluetoothProfile.STATE_CONNECTING).isEqualTo(
- intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
+ // Verify that one connection state change is notifyed
+ verify(mLeAudioService, timeout(TIMEOUT_MS))
+ .notifyConnectionStateChanged(
+ any(), eq(BluetoothProfile.STATE_CONNECTING), anyInt());
// Check that we are in Connecting state
assertThat(mLeAudioStateMachine.getCurrentState())
@@ -164,11 +163,14 @@ public class LeAudioStateMachineTest {
connCompletedEvent.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_CONNECTED;
mLeAudioStateMachine.sendMessage(LeAudioStateMachine.STACK_EVENT, connCompletedEvent);
- // Verify that the expected number of broadcasts are executed:
- // - two calls to broadcastConnectionState(): Disconnected -> Conecting -> Connected
- ArgumentCaptor<Intent> intentArgument2 = ArgumentCaptor.forClass(Intent.class);
- verify(mLeAudioService, timeout(TIMEOUT_MS).times(2)).sendBroadcast(
- intentArgument2.capture(), anyString(), any(Bundle.class));
+ // Verify that the expected number of notification are called:
+ // - two calls to notifyConnectionStateChanged(): Disconnected -> Connecting -> Connected
+ verify(mLeAudioService, timeout(TIMEOUT_MS))
+ .notifyConnectionStateChanged(
+ any(), eq(BluetoothProfile.STATE_CONNECTING), anyInt());
+ verify(mLeAudioService, timeout(TIMEOUT_MS))
+ .notifyConnectionStateChanged(
+ any(), eq(BluetoothProfile.STATE_CONNECTED), anyInt());
// Check that we are in Connected state
assertThat(mLeAudioStateMachine.getCurrentState())
.isInstanceOf(LeAudioStateMachine.Connected.class);
@@ -188,25 +190,19 @@ public class LeAudioStateMachineTest {
// Send a connect request
mLeAudioStateMachine.sendMessage(LeAudioStateMachine.CONNECT, mTestDevice);
- // Verify that one connection state broadcast is executed
- ArgumentCaptor<Intent> intentArgument1 = ArgumentCaptor.forClass(Intent.class);
- verify(mLeAudioService, timeout(TIMEOUT_MS).times(1)).sendBroadcast(
- intentArgument1.capture(),
- anyString(), any(Bundle.class));
- assertThat(BluetoothProfile.STATE_CONNECTING).isEqualTo(
- intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
+ // Verify that one connection state change is notified
+ verify(mLeAudioService, timeout(TIMEOUT_MS))
+ .notifyConnectionStateChanged(
+ any(), eq(BluetoothProfile.STATE_CONNECTING), anyInt());
// Check that we are in Connecting state
assertThat(mLeAudioStateMachine.getCurrentState())
.isInstanceOf(LeAudioStateMachine.Connecting.class);
- // Verify that one connection state broadcast is executed
- ArgumentCaptor<Intent> intentArgument2 = ArgumentCaptor.forClass(Intent.class);
- verify(mLeAudioService, timeout(LeAudioStateMachine.sConnectTimeoutMs * 2).times(
- 2)).sendBroadcast(intentArgument2.capture(), anyString(),
- any(Bundle.class));
- assertThat(BluetoothProfile.STATE_DISCONNECTED).isEqualTo(
- intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
+ // Verify that one connection state change is notified
+ verify(mLeAudioService, timeout(LeAudioStateMachine.sConnectTimeoutMs * 2))
+ .notifyConnectionStateChanged(
+ any(), eq(BluetoothProfile.STATE_DISCONNECTED), anyInt());
// Check that we are in Disconnected state
assertThat(mLeAudioStateMachine.getCurrentState())
@@ -231,25 +227,19 @@ public class LeAudioStateMachineTest {
connStCh.valueInt1 = LeAudioStackEvent.CONNECTION_STATE_CONNECTING;
mLeAudioStateMachine.sendMessage(LeAudioStateMachine.STACK_EVENT, connStCh);
- // Verify that one connection state broadcast is executed
- ArgumentCaptor<Intent> intentArgument1 = ArgumentCaptor.forClass(Intent.class);
- verify(mLeAudioService, timeout(TIMEOUT_MS).times(1)).sendBroadcast(
- intentArgument1.capture(),
- anyString(), any(Bundle.class));
- assertThat(BluetoothProfile.STATE_CONNECTING).isEqualTo(
- intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
+ // Verify that one connection state change is notified
+ verify(mLeAudioService, timeout(TIMEOUT_MS))
+ .notifyConnectionStateChanged(
+ any(), eq(BluetoothProfile.STATE_CONNECTING), anyInt());
// Check that we are in Connecting state
assertThat(mLeAudioStateMachine.getCurrentState())
.isInstanceOf(LeAudioStateMachine.Connecting.class);
- // Verify that one connection state broadcast is executed
- ArgumentCaptor<Intent> intentArgument2 = ArgumentCaptor.forClass(Intent.class);
- verify(mLeAudioService, timeout(LeAudioStateMachine.sConnectTimeoutMs * 2).times(
- 2)).sendBroadcast(intentArgument2.capture(), anyString(),
- any(Bundle.class));
- assertThat(intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1))
- .isEqualTo(BluetoothProfile.STATE_DISCONNECTED);
+ // Verify that one connection state change is notified
+ verify(mLeAudioService, timeout(LeAudioStateMachine.sConnectTimeoutMs * 2))
+ .notifyConnectionStateChanged(
+ any(), eq(BluetoothProfile.STATE_DISCONNECTED), anyInt());
// Check that we are in Disconnected state
assertThat(mLeAudioStateMachine.getCurrentState())
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/asha_test.py b/android/pandora/test/asha_test.py
index 90493ce0ae..83b8d456d8 100644
--- a/android/pandora/test/asha_test.py
+++ b/android/pandora/test/asha_test.py
@@ -865,6 +865,9 @@ class AshaTest(base_test.BaseTestClass): # type: ignore[misc]
Verify that DUT sends a correct AudioControlPoint `Stop` command.
"""
+ # TODO(b/290204194) Re-activate this test ASAP
+ raise signals.TestSkip('TODO(b/290204194) Re-activate this test ASAP')
+
async def ref_device_connect(ref_device: BumblePandoraDevice, ear: Ear) -> Tuple[Connection, Connection]:
advertisement = await self.ref_advertise_asha(ref_device=ref_device, ref_address_type=RANDOM, ear=ear)
ref = await self.dut_scan_for_asha(dut_address_type=RANDOM, ear=ear)
@@ -1061,6 +1064,9 @@ class AshaTest(base_test.BaseTestClass): # type: ignore[misc]
Verify Refs cannot recevice audio data after DUT stops media streaming.
"""
+ # TODO(b/290204194) Re-activate this test ASAP
+ raise signals.TestSkip('TODO(b/290204194) Re-activate this test ASAP')
+
async def ref_device_connect(ref_device: BumblePandoraDevice, ear: Ear) -> Tuple[Connection, Connection]:
advertisement = await self.ref_advertise_asha(ref_device=ref_device, ref_address_type=RANDOM, ear=ear)
ref = await self.dut_scan_for_asha(dut_address_type=RANDOM, ear=ear)
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/floss/hcidoc/src/groups/informational.rs b/floss/hcidoc/src/groups/informational.rs
index d908ce11e4..f3f38afb2d 100644
--- a/floss/hcidoc/src/groups/informational.rs
+++ b/floss/hcidoc/src/groups/informational.rs
@@ -4,6 +4,7 @@ use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::convert::Into;
use std::fmt;
+use std::hash::Hash;
use std::io::Write;
use crate::engine::{Rule, RuleGroup, Signal};
@@ -18,6 +19,20 @@ type ConnectionHandle = u16;
const INVALID_TS: NaiveDateTime = NaiveDateTime::MAX;
+fn print_start_end_timestamps(start: NaiveDateTime, end: NaiveDateTime) -> String {
+ fn print_time(ts: NaiveDateTime) -> String {
+ if ts == INVALID_TS {
+ return "N/A".to_owned();
+ }
+ return format!("{}", ts.time());
+ }
+
+ if start == end && start != INVALID_TS {
+ return format!("{} - Failed", start.time());
+ }
+ return format!("{} to {}", print_time(start), print_time(end));
+}
+
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
enum AddressType {
None,
@@ -110,6 +125,33 @@ impl DeviceInformation {
}
}
+ fn is_connection_active(&self) -> bool {
+ // not empty and last connection's end time is not set.
+ return !self.acls.is_empty() && self.acls.last().unwrap().end_time == INVALID_TS;
+ }
+
+ fn get_or_allocate_connection(&mut self, handle: &ConnectionHandle) -> &mut AclInformation {
+ if !self.is_connection_active() {
+ let acl = AclInformation::new(*handle);
+ self.acls.push(acl);
+ }
+ return self.acls.last_mut().unwrap();
+ }
+
+ fn report_connection_start(&mut self, handle: ConnectionHandle, ts: NaiveDateTime) {
+ let mut acl = AclInformation::new(handle);
+ let initiator = self.acl_state.into();
+ acl.report_start(initiator, ts);
+ self.acls.push(acl);
+ self.acl_state = AclState::Connected;
+ }
+
+ fn report_connection_end(&mut self, handle: ConnectionHandle, ts: NaiveDateTime) {
+ let acl = self.get_or_allocate_connection(&handle);
+ acl.report_end(ts);
+ self.acl_state = AclState::None;
+ }
+
fn print_names(names: &HashSet<String>) -> String {
if names.len() > 1 {
format!("{:?}", names)
@@ -143,6 +185,7 @@ struct AclInformation {
end_time: NaiveDateTime,
handle: ConnectionHandle,
initiator: InitiatorType,
+ profiles: HashMap<ProfileType, Vec<ProfileInformation>>,
}
impl AclInformation {
@@ -152,31 +195,128 @@ impl AclInformation {
end_time: INVALID_TS,
handle: handle,
initiator: InitiatorType::Unknown,
+ profiles: HashMap::new(),
+ }
+ }
+
+ fn get_or_allocate_profile(&mut self, profile_type: &ProfileType) -> &mut ProfileInformation {
+ if !self.profiles.contains_key(profile_type)
+ || self.profiles.get(profile_type).unwrap().last().unwrap().end_time != INVALID_TS
+ {
+ self.profiles.insert(*profile_type, vec![ProfileInformation::new(*profile_type)]);
+ }
+
+ return self.profiles.get_mut(profile_type).unwrap().last_mut().unwrap();
+ }
+
+ fn report_start(&mut self, initiator: InitiatorType, ts: NaiveDateTime) {
+ self.initiator = initiator;
+ self.start_time = ts;
+ }
+
+ fn report_end(&mut self, ts: NaiveDateTime) {
+ // disconnect the active profiles
+ let profile_types: Vec<ProfileType> = self.profiles.keys().cloned().collect();
+ for profile_type in profile_types {
+ if let Some(profile) = self.profiles.get(&profile_type).unwrap().last() {
+ if profile.end_time != INVALID_TS {
+ self.report_profile_end(profile_type, ts);
+ }
+ }
+ }
+ self.end_time = ts;
+ }
+
+ fn report_profile_start(
+ &mut self,
+ profile_type: ProfileType,
+ initiator: InitiatorType,
+ ts: NaiveDateTime,
+ ) {
+ let mut profile = ProfileInformation::new(profile_type);
+ profile.report_start(initiator, ts);
+ if !self.profiles.contains_key(&profile_type) {
+ self.profiles.insert(profile_type, vec![]);
}
+ self.profiles.get_mut(&profile_type).unwrap().push(profile);
+ }
+
+ fn report_profile_end(&mut self, profile_type: ProfileType, ts: NaiveDateTime) {
+ let profile = self.get_or_allocate_profile(&profile_type);
+ profile.report_end(ts);
}
}
impl fmt::Display for AclInformation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fn print_time(ts: NaiveDateTime) -> String {
- if ts == INVALID_TS {
- return "N/A".to_owned();
+ let _ = writeln!(
+ f,
+ " Handle: {handle}, {initiator}, {timestamp_info}",
+ handle = self.handle,
+ initiator = self.initiator,
+ timestamp_info = print_start_end_timestamps(self.start_time, self.end_time)
+ );
+
+ for (_profile_type, profiles) in self.profiles.iter() {
+ for profile in profiles {
+ let _ = write!(f, "{}", profile);
}
- return format!("{}", ts.time());
}
- fn print_timestamps(start: NaiveDateTime, end: NaiveDateTime) -> String {
- if start == end {
- return format!("{} - Failed", start.time());
- }
- return format!("{} to {}", print_time(start), print_time(end));
+
+ Ok(())
+ }
+}
+
+// Currently only HFP is possible to be detected. Other profiles needs us to parse L2CAP packets.
+#[derive(Copy, Clone, Eq, PartialEq, Hash)]
+enum ProfileType {
+ HFP,
+}
+
+impl fmt::Display for ProfileType {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let str = match self {
+ ProfileType::HFP => "HFP",
+ };
+ write!(f, "{}", str)
+ }
+}
+
+struct ProfileInformation {
+ start_time: NaiveDateTime,
+ end_time: NaiveDateTime,
+ profile_type: ProfileType,
+ initiator: InitiatorType,
+}
+
+impl ProfileInformation {
+ pub fn new(profile_type: ProfileType) -> Self {
+ ProfileInformation {
+ start_time: INVALID_TS,
+ end_time: INVALID_TS,
+ profile_type: profile_type,
+ initiator: InitiatorType::Unknown,
}
+ }
+
+ fn report_start(&mut self, initiator: InitiatorType, ts: NaiveDateTime) {
+ self.initiator = initiator;
+ self.start_time = ts;
+ }
+
+ fn report_end(&mut self, ts: NaiveDateTime) {
+ self.end_time = ts;
+ }
+}
+impl fmt::Display for ProfileInformation {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(
f,
- " Handle: {handle}, {initiator}, {timestamp_info}",
- handle = self.handle,
+ " {profile}, {initiator}, {timestamp_info}",
+ profile = self.profile_type,
initiator = self.initiator,
- timestamp_info = print_timestamps(self.start_time, self.end_time)
+ timestamp_info = print_start_end_timestamps(self.start_time, self.end_time)
)
}
}
@@ -185,6 +325,7 @@ impl fmt::Display for AclInformation {
struct InformationalRule {
devices: HashMap<Address, DeviceInformation>,
handles: HashMap<ConnectionHandle, Address>,
+ sco_handles: HashMap<ConnectionHandle, ConnectionHandle>,
// unknownConnections store connections which is initiated before btsnoop starts.
unknown_connections: HashMap<ConnectionHandle, AclInformation>,
}
@@ -194,6 +335,7 @@ impl InformationalRule {
InformationalRule {
devices: HashMap::new(),
handles: HashMap::new(),
+ sco_handles: HashMap::new(),
unknown_connections: HashMap::new(),
}
}
@@ -215,19 +357,30 @@ impl InformationalRule {
return self.unknown_connections.get_mut(handle).unwrap();
}
+ fn get_or_allocate_connection(&mut self, handle: &ConnectionHandle) -> &mut AclInformation {
+ if !self.handles.contains_key(&handle) {
+ let conn = self.get_or_allocate_unknown_connection(&handle);
+ return conn;
+ }
+
+ let address = &self.handles.get(handle).unwrap().clone();
+ let device = self.get_or_allocate_device(address);
+ return device.get_or_allocate_connection(handle);
+ }
+
fn report_address_type(&mut self, address: &Address, address_type: AddressType) {
- let info = self.get_or_allocate_device(address);
- info.address_type.update(address_type);
+ let device = self.get_or_allocate_device(address);
+ device.address_type.update(address_type);
}
fn report_name(&mut self, address: &Address, name: &String) {
- let info = self.get_or_allocate_device(address);
- info.names.insert(name.into());
+ let device = self.get_or_allocate_device(address);
+ device.names.insert(name.into());
}
fn report_acl_state(&mut self, address: &Address, state: AclState) {
- let info = self.get_or_allocate_device(address);
- info.acl_state = state;
+ let device = self.get_or_allocate_device(address);
+ device.acl_state = state;
}
fn report_connection_start(
@@ -236,38 +389,62 @@ impl InformationalRule {
handle: ConnectionHandle,
ts: NaiveDateTime,
) {
- let info = self.get_or_allocate_device(address);
- info.acls.push(AclInformation {
- start_time: ts,
- end_time: INVALID_TS,
- handle: handle,
- initiator: info.acl_state.into(),
- });
- info.acl_state = AclState::Connected;
+ let device = self.get_or_allocate_device(address);
+ device.report_connection_start(handle, ts);
self.handles.insert(handle, *address);
}
+ fn report_sco_connection_start(
+ &mut self,
+ address: &Address,
+ handle: ConnectionHandle,
+ ts: NaiveDateTime,
+ ) {
+ if !self.devices.contains_key(address) {
+ // To simplify things, let's not process unknown devices
+ return;
+ }
+
+ let device = self.devices.get_mut(address).unwrap();
+ if !device.is_connection_active() {
+ // SCO is connected, but ACL is not. This is weird, but let's ignore for simplicity.
+ eprintln!("[{}] SCO is connected, but ACL is not.", address);
+ return;
+ }
+
+ // Whatever handle value works here - we aren't allocating a new one.
+ let acl = device.get_or_allocate_connection(&0);
+ let acl_handle = acl.handle;
+ // We need to listen the HCI commands to determine the correct initiator.
+ // Here we just assume host for simplicity.
+ acl.report_profile_start(ProfileType::HFP, InitiatorType::Host, ts);
+
+ self.sco_handles.insert(handle, acl_handle);
+ }
+
fn report_connection_end(&mut self, handle: ConnectionHandle, ts: NaiveDateTime) {
- if !self.handles.contains_key(&handle) {
- let conn = self.get_or_allocate_unknown_connection(&handle);
- conn.end_time = ts;
+ // This might be a SCO disconnection event, so check that first
+ if self.sco_handles.contains_key(&handle) {
+ let acl_handle = self.sco_handles[&handle];
+ let conn = self.get_or_allocate_connection(&acl_handle);
+ conn.report_profile_end(ProfileType::HFP, ts);
return;
}
- let info = self.get_or_allocate_device(&self.handles.get(&handle).unwrap().clone());
-
- // If we can't find the matching acl connection, create one.
- if info.acls.is_empty() || info.acls.last().unwrap().end_time != INVALID_TS {
- info.acls.push(AclInformation {
- start_time: INVALID_TS,
- end_time: ts,
- handle: handle,
- initiator: InitiatorType::Unknown,
- });
+
+ // Not recognized as SCO, assume it's an ACL handle.
+ if let Some(address) = self.handles.get(&handle) {
+ // This device is known
+ let device = self.devices.get_mut(address).unwrap();
+ device.report_connection_end(handle, ts);
+ self.handles.remove(&handle);
+
+ // remove the associated SCO handle, if any
+ self.sco_handles.retain(|_sco_handle, acl_handle| *acl_handle != handle);
} else {
- info.acls.last_mut().unwrap().end_time = ts;
+ // Unknown device.
+ let conn = self.get_or_allocate_unknown_connection(&handle);
+ conn.report_end(ts);
}
- info.acl_state = AclState::None;
- self.handles.remove(&handle);
}
fn report_reset(&mut self, ts: NaiveDateTime) {
@@ -276,6 +453,28 @@ impl InformationalRule {
for handle in handles {
self.report_connection_end(handle, ts);
}
+ self.sco_handles.clear();
+ }
+
+ fn _report_profile_start(
+ &mut self,
+ handle: ConnectionHandle,
+ profile_type: ProfileType,
+ initiator: InitiatorType,
+ ts: NaiveDateTime,
+ ) {
+ let conn = self.get_or_allocate_connection(&handle);
+ conn.report_profile_start(profile_type, initiator, ts);
+ }
+
+ fn _report_profile_end(
+ &mut self,
+ handle: ConnectionHandle,
+ profile_type: ProfileType,
+ ts: NaiveDateTime,
+ ) {
+ let conn = self.get_or_allocate_connection(&handle);
+ conn.report_profile_end(profile_type, ts);
}
fn process_gap_data(&mut self, address: &Address, data: &GapData) {
@@ -325,6 +524,18 @@ impl Rule for InformationalRule {
}
}
+ EventChild::SynchronousConnectionComplete(ev) => {
+ self.report_sco_connection_start(
+ &ev.get_bd_addr(),
+ ev.get_connection_handle(),
+ packet.ts,
+ );
+ // If failed, assume it's the end of connection.
+ if ev.get_status() != ErrorCode::Success {
+ self.report_connection_end(ev.get_connection_handle(), packet.ts);
+ }
+ }
+
EventChild::DisconnectionComplete(ev) => {
self.report_connection_end(ev.get_connection_handle(), packet.ts);
}
@@ -487,7 +698,7 @@ impl Rule for InformationalRule {
return Ordering::Equal;
}
- if self.devices.is_empty() {
+ if self.devices.is_empty() && self.unknown_connections.is_empty() {
return;
}
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/binder/android/bluetooth/IBluetoothGatt.aidl b/system/binder/android/bluetooth/IBluetoothGatt.aidl
index 221deaa7b1..8c5305e02a 100644
--- a/system/binder/android/bluetooth/IBluetoothGatt.aidl
+++ b/system/binder/android/bluetooth/IBluetoothGatt.aidl
@@ -47,11 +47,6 @@ import com.android.modules.utils.SynchronousResultReceiver;
*/
oneway interface IBluetoothGatt {
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void startService();
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void stopService();
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void getDevicesMatchingConnectionStates(in int[] states, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)")
@@ -181,8 +176,6 @@ oneway interface IBluetoothGatt {
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void disconnectAll(in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void unregAll(in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void numHwTrackFiltersAvailable(in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void leSubrateRequest(in int clientIf, in String address, in int subrateMin, in int subrateMax, in int maxLatency,
diff --git a/system/bta/Android.bp b/system/bta/Android.bp
index 8a3cd65a37..0805b45f6e 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",
@@ -131,6 +131,7 @@ cc_library_static {
static_libs: [
"avrcp-target-service",
"lib-bt-packets",
+ "libbluetooth_gd",
"libbt-bta-core",
"libcom.android.sysprop.bluetooth",
],
@@ -147,6 +148,9 @@ cc_library_static {
],
},
},
+ apex_available: [
+ "com.android.btservices",
+ ],
host_supported: true,
min_sdk_version: "Tiramisu",
}
@@ -189,6 +193,9 @@ cc_library_static {
"lib-bt-packets",
"libcom.android.sysprop.bluetooth",
],
+ apex_available: [
+ "com.android.btservices",
+ ],
host_supported: true,
min_sdk_version: "Tiramisu",
}
@@ -233,11 +240,11 @@ cc_test {
static_libs: [
"crypto_toolbox_for_tests",
"libbluetooth-types",
+ "libbluetooth_gd",
"libbt-audio-hal-interface",
"libbt-bta",
"libbt-bta-core",
"libbt-common",
- "libbt-protos-lite",
"libbtcore",
"libchrome",
"libcom.android.sysprop.bluetooth",
@@ -279,11 +286,11 @@ cc_test {
static_libs: [
"crypto_toolbox_for_tests",
"libbluetooth-types",
+ "libbluetooth_gd",
"libbt-audio-hal-interface",
"libbt-bta",
"libbt-bta-core",
"libbt-common",
- "libbt-protos-lite",
"libbtcore",
"libchrome",
"libosi",
@@ -397,14 +404,13 @@ cc_test {
],
static_libs: [
"libbluetooth-types",
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libbtcore",
"libbtdevice",
"libchrome",
"libcom.android.sysprop.bluetooth",
"libevent",
- "libflatbuffers-cpp",
"libgmock",
],
sanitize: {
@@ -459,8 +465,8 @@ cc_test {
],
static_libs: [
"crypto_toolbox_for_tests",
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libgmock",
"libosi",
@@ -503,8 +509,8 @@ cc_test {
],
static_libs: [
"crypto_toolbox_for_tests",
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libgmock",
"libosi",
@@ -558,8 +564,8 @@ cc_test {
],
static_libs: [
"crypto_toolbox_for_tests",
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libgmock",
"libosi",
@@ -722,8 +728,8 @@ cc_test {
"liblog", // __android_log_print
],
static_libs: [
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libevent",
"libflatbuffers-cpp",
@@ -793,9 +799,9 @@ cc_test {
],
static_libs: [
"crypto_toolbox_for_tests",
+ "libbluetooth_gd",
"libbt-audio-hal-interface",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libevent",
"libflatbuffers-cpp",
@@ -857,8 +863,8 @@ cc_test {
],
static_libs: [
"crypto_toolbox_for_tests",
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libgmock",
"libosi",
@@ -910,8 +916,8 @@ cc_test {
"liblog",
],
static_libs: [
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libgmock",
"liblc3",
@@ -975,7 +981,6 @@ cc_test {
static_libs: [
"libbt-audio-hal-interface",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libevent",
"libgmock",
@@ -1035,8 +1040,8 @@ cc_test {
],
static_libs: [
"crypto_toolbox_for_tests",
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libgmock",
],
@@ -1097,8 +1102,8 @@ cc_test {
],
static_libs: [
"crypto_toolbox_for_tests",
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libcom.android.sysprop.bluetooth",
"libevent",
diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc
index 48a2bd6a46..0782e049c6 100644
--- a/system/bta/dm/bta_dm_act.cc
+++ b/system/bta/dm/bta_dm_act.cc
@@ -846,8 +846,11 @@ void bta_dm_close_acl(const RawAddress& bd_addr, bool remove_dev,
break;
}
if (index != bta_dm_cb.device_list.count) {
- if (remove_dev)
+ if (remove_dev) {
+ LOG_INFO("Setting remove_dev_pending for %s",
+ ADDRESS_TO_LOGGABLE_CSTR(bd_addr));
bta_dm_cb.device_list.peer_device[index].remove_dev_pending = true;
+ }
} else {
APPL_TRACE_ERROR("unknown device, remove ACL failed");
}
@@ -1080,8 +1083,8 @@ static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr,
bta_dm_search_cb.peer_bdaddr = bd_addr;
bta_dm_search_cb.peer_name[0] = 0;
- btm_status = BTM_ReadRemoteDeviceName(bta_dm_search_cb.peer_bdaddr,
- bta_dm_remname_cback, transport);
+ btm_status = get_btm_client_interface().peer.BTM_ReadRemoteDeviceName(
+ bta_dm_search_cb.peer_bdaddr, bta_dm_remname_cback, transport);
if (btm_status == BTM_CMD_STARTED) {
APPL_TRACE_DEBUG("%s: BTM_ReadRemoteDeviceName is started", __func__);
@@ -1094,7 +1097,8 @@ static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr,
* "bta_dm_remname_cback" */
/* adding callback to get notified that current reading remote name done */
- BTM_SecAddRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
+ get_btm_client_interface().security.BTM_SecAddRmtNameNotifyCallback(
+ &bta_dm_service_search_remname_cback);
return (true);
} else {
@@ -1420,7 +1424,8 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) {
/* callbacks */
/* start next bd_addr if necessary */
- BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
+ get_btm_client_interface().security.BTM_SecDeleteRmtNameNotifyCallback(
+ &bta_dm_service_search_remname_cback);
BTM_LogHistory(
kBtmLogTag, bta_dm_search_cb.peer_bdaddr, "Discovery completed",
@@ -1490,7 +1495,8 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) {
if (bta_dm_search_cb.p_sdp_db)
osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db);
- BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
+ get_btm_client_interface().security.BTM_SecDeleteRmtNameNotifyCallback(
+ &bta_dm_service_search_remname_cback);
p_msg = (tBTA_DM_MSG*)osi_calloc(sizeof(tBTA_DM_MSG));
p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
@@ -2053,8 +2059,8 @@ static void bta_dm_discover_device(const RawAddress& remote_bd_addr) {
if connection exists, we don't have to wait for ACL
link to go down to start search on next device */
if (transport == BT_TRANSPORT_BR_EDR) {
- if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr,
- BT_TRANSPORT_BR_EDR))
+ if (get_btm_client_interface().peer.BTM_IsAclConnectionUp(
+ bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR))
bta_dm_search_cb.wait_disc = false;
else
bta_dm_search_cb.wait_disc = true;
@@ -2269,13 +2275,15 @@ static void bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME* p_remote_name) {
p_remote_name->remote_bd_name[0], p_remote_name->length);
if (bta_dm_search_cb.peer_bdaddr == p_remote_name->bd_addr) {
- BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
+ get_btm_client_interface().security.BTM_SecDeleteRmtNameNotifyCallback(
+ &bta_dm_service_search_remname_cback);
} else {
// if we got a different response, maybe ignore it
// we will have made a request directly from BTM_ReadRemoteDeviceName so we
// expect a dedicated response for us
if (p_remote_name->hci_status == HCI_ERR_CONNECTION_EXISTS) {
- BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
+ get_btm_client_interface().security.BTM_SecDeleteRmtNameNotifyCallback(
+ &bta_dm_service_search_remname_cback);
LOG_INFO(
"Assume command failed due to disconnection hci_status:%s peer:%s",
hci_error_code_text(p_remote_name->hci_status).c_str(),
@@ -2903,6 +2911,8 @@ static void bta_dm_acl_down(const RawAddress& bd_addr,
}
}
if (remove_device) {
+ LOG_INFO("remove_dev_pending actually removing %s",
+ ADDRESS_TO_LOGGABLE_CSTR(bd_addr));
bta_dm_process_remove_device_no_callback(bd_addr);
}
@@ -3068,8 +3078,13 @@ static void bta_dm_delay_role_switch_cback(UNUSED_ATTR void* data) {
******************************************************************************/
static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr) {
for (size_t i = 0; i < bta_dm_cb.device_list.count; i++) {
- if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == remote_bd_addr) {
- bta_dm_cb.device_list.peer_device[i].remove_dev_pending = false;
+ auto& dev = bta_dm_cb.device_list.peer_device[i];
+ if (dev.peer_bdaddr == remote_bd_addr) {
+ if (dev.remove_dev_pending) {
+ LOG_INFO("Clearing remove_dev_pending for %s",
+ ADDRESS_TO_LOGGABLE_CSTR(dev.peer_bdaddr));
+ dev.remove_dev_pending = false;
+ }
return;
}
}
@@ -3096,8 +3111,11 @@ static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr) {
__func__);
BTM_SecClearSecurityFlags(remote_bd_addr);
for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
- if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == remote_bd_addr) {
- bta_dm_cb.device_list.peer_device[i].remove_dev_pending = TRUE;
+ auto& dev = bta_dm_cb.device_list.peer_device[i];
+ if (dev.peer_bdaddr == remote_bd_addr) {
+ LOG_INFO("Setting remove_dev_pending for %s",
+ ADDRESS_TO_LOGGABLE_CSTR(dev.peer_bdaddr));
+ dev.remove_dev_pending = TRUE;
break;
}
}
@@ -3169,7 +3187,8 @@ static const char* bta_dm_get_remname(void) {
/* If the name isn't already stored, try retrieving from BTM */
if (*p_name == '\0') {
- const char* p_temp = BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr);
+ const char* p_temp = get_btm_client_interface().security.BTM_SecReadDevName(
+ bta_dm_search_cb.peer_bdaddr);
if (p_temp != NULL) p_name = (const char*)p_temp;
}
@@ -3970,6 +3989,12 @@ static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda,
sec_event.ble_key.key_type = p_data->key.key_type;
sec_event.ble_key.p_key_value = p_data->key.p_key_value;
bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event);
+
+ // Setting remove_dev_pending flag to false, where it will avoid deleting
+ // the security device record when the ACL connection link goes down in
+ // case of reconnection.
+ if (bta_dm_cb.device_list.count) bta_dm_reset_sec_dev_pending(bda);
+
break;
case BTM_LE_COMPLT_EVT:
@@ -4450,7 +4475,7 @@ void btm_dm_start_gatt_discovery(const RawAddress& bd_addr) {
* Parameters:
*
******************************************************************************/
-void bta_dm_proc_open_evt(tBTA_GATTC_OPEN* p_data) {
+static void bta_dm_proc_open_evt(tBTA_GATTC_OPEN* p_data) {
VLOG(1) << "DM Search state= " << bta_dm_search_get_state()
<< " search_cb.peer_dbaddr:" << bta_dm_search_cb.peer_bdaddr
<< " connected_bda=" << p_data->remote_bda.address;
diff --git a/system/bta/test/bta_dm_test.cc b/system/bta/test/bta_dm_test.cc
index 43c3c2a794..f40bb815d7 100644
--- a/system/bta/test/bta_dm_test.cc
+++ b/system/bta/test/bta_dm_test.cc
@@ -42,6 +42,7 @@
#include "test/mock/mock_osi_alarm.h"
#include "test/mock/mock_osi_allocator.h"
#include "test/mock/mock_stack_acl.h"
+#include "test/mock/mock_stack_btm.h"
#include "test/mock/mock_stack_btm_ble.h"
#include "test/mock/mock_stack_btm_inq.h"
#include "test/mock/mock_stack_btm_sec.h"
@@ -50,8 +51,6 @@
using namespace std::chrono_literals;
using ::testing::ElementsAre;
-extern struct btm_client_interface_t btm_client_interface;
-
namespace base {
class MessageLoop;
} // namespace base
@@ -106,6 +105,7 @@ class BtaDmTest : public testing::Test {
bluetooth::legacy::testing::bta_dm_deinit_cb();
post_on_bt_main([]() { LOG_INFO("Main thread shutting down"); });
main_thread_shut_down();
+ btm_client_interface = {};
}
std::unique_ptr<test::fake::FakeOsi> fake_osi_;
@@ -392,6 +392,11 @@ TEST_F(BtaDmTest, bta_dm_remname_cback__typical) {
strlcpy(reinterpret_cast<char*>(&name.remote_bd_name), kRemoteName,
strlen(kRemoteName));
+ btm_client_interface.security.BTM_SecDeleteRmtNameNotifyCallback =
+ [](tBTM_RMT_NAME_CALLBACK*) -> bool {
+ inc_func_call_count("BTM_SecDeleteRmtNameNotifyCallback");
+ return true;
+ };
bluetooth::legacy::testing::bta_dm_remname_cback(&name);
sync_main_handler();
@@ -416,6 +421,11 @@ TEST_F(BtaDmTest, bta_dm_remname_cback__wrong_address) {
strlcpy(reinterpret_cast<char*>(&name.remote_bd_name), kRemoteName,
strlen(kRemoteName));
+ btm_client_interface.security.BTM_SecDeleteRmtNameNotifyCallback =
+ [](tBTM_RMT_NAME_CALLBACK*) -> bool {
+ inc_func_call_count("BTM_SecDeleteRmtNameNotifyCallback");
+ return true;
+ };
bluetooth::legacy::testing::bta_dm_remname_cback(&name);
sync_main_handler();
@@ -440,6 +450,11 @@ TEST_F(BtaDmTest, bta_dm_remname_cback__HCI_ERR_CONNECTION_EXISTS) {
strlcpy(reinterpret_cast<char*>(&name.remote_bd_name), kRemoteName,
strlen(kRemoteName));
+ btm_client_interface.security.BTM_SecDeleteRmtNameNotifyCallback =
+ [](tBTM_RMT_NAME_CALLBACK*) -> bool {
+ inc_func_call_count("BTM_SecDeleteRmtNameNotifyCallback");
+ return true;
+ };
bluetooth::legacy::testing::bta_dm_remname_cback(&name);
sync_main_handler();
diff --git a/system/bta/test/bta_sdp_test.cc b/system/bta/test/bta_sdp_test.cc
index b91c44d51a..52775f0cc2 100644
--- a/system/bta/test/bta_sdp_test.cc
+++ b/system/bta/test/bta_sdp_test.cc
@@ -30,6 +30,10 @@
void BTA_dm_on_hw_on();
void BTA_dm_on_hw_off();
+namespace {
+const char kName[] = "Hello";
+}
+
class BtaSdpTest : public testing::Test {
protected:
void SetUp() override {
@@ -100,5 +104,9 @@ TEST_F(BtaSdpRegisteredTest, bta_dm_sdp_result_SDP_SUCCESS) {
.sdp_result = SDP_SUCCESS,
},
};
+ btm_client_interface.security.BTM_SecReadDevName =
+ [](const RawAddress& bd_addr) -> const char* { return kName; };
+ btm_client_interface.security.BTM_SecDeleteRmtNameNotifyCallback =
+ [](tBTM_RMT_NAME_CALLBACK*) -> bool { return true; };
bta_dm_sdp_result(&msg);
}
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 08df424495..097d66908d 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
@@ -162,13 +160,16 @@ cc_library_static {
cflags: [
"-DBUILDCFG",
],
+ apex_available: [
+ "com.android.btservices",
+ ],
host_supported: true,
min_sdk_version: "Tiramisu",
}
cc_library_static {
name: "libbtif-core",
- defaults: ["fluoride_basic_defaults"],
+ defaults: ["fluoride_defaults"],
include_dirs: btifCommonIncludes,
srcs: [
// Callouts
@@ -237,6 +238,9 @@ cc_library_static {
"-DBUILDCFG",
"-fvisibility=default",
],
+ apex_available: [
+ "com.android.btservices",
+ ],
host_supported: true,
min_sdk_version: "Tiramisu",
}
@@ -269,7 +273,7 @@ cc_test {
"libutils",
],
static_libs: [
- "android.hardware.audio.common-V1-ndk",
+ "android.hardware.audio.common-V2-ndk",
"android.hardware.bluetooth.a2dp@1.0",
"android.hardware.bluetooth.audio-V3-ndk",
"android.hardware.bluetooth@1.0",
@@ -286,7 +290,6 @@ cc_test {
"libbt-bta-core",
"libbt-common",
"libbt-hci",
- "libbt-protos-lite",
"libbt-sbc-decoder",
"libbt-sbc-encoder",
"libbt-stack",
@@ -342,8 +345,8 @@ cc_test {
],
static_libs: [
"libbluetooth-types",
+ "libbluetooth_gd",
"libchrome",
- "libflatbuffers-cpp",
"libosi",
],
cflags: ["-DBUILDCFG"],
@@ -376,7 +379,6 @@ cc_test {
static_libs: [
"libbluetooth-types",
"libchrome",
- "libflatbuffers-cpp",
"libosi",
],
cflags: ["-DBUILDCFG"],
@@ -412,8 +414,8 @@ cc_test {
],
static_libs: [
"libbluetooth-types",
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libevent",
"libosi-AllocationTestHarness",
@@ -595,6 +597,7 @@ cc_test {
"lib-bt-packets-base",
"libaudio-a2dp-hw-utils",
"libbluetooth-types",
+ "libbluetooth_gd",
"libbt-audio-hal-interface",
"libbt-sbc-decoder",
"libbt-sbc-encoder",
@@ -607,14 +610,13 @@ cc_test {
"libchrome",
"libcom.android.sysprop.bluetooth",
"libevent",
- "libflatbuffers-cpp",
"libgmock",
],
cflags: ["-DBUILDCFG"],
target: {
android: {
static_libs: [
- "android.hardware.audio.common-V1-ndk",
+ "android.hardware.audio.common-V2-ndk",
"android.hardware.bluetooth.audio-V3-ndk",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
@@ -729,6 +731,7 @@ cc_test {
"lib-bt-packets-base",
"libaudio-a2dp-hw-utils",
"libbluetooth-types",
+ "libbluetooth_gd",
"libbt-audio-hal-interface",
"libbt-sbc-decoder",
"libbt-sbc-encoder",
@@ -739,14 +742,13 @@ cc_test {
"libchrome",
"libcom.android.sysprop.bluetooth",
"libevent",
- "libflatbuffers-cpp",
"libgmock",
],
cflags: ["-DBUILDCFG"],
target: {
android: {
static_libs: [
- "android.hardware.audio.common-V1-ndk",
+ "android.hardware.audio.common-V2-ndk",
"android.hardware.bluetooth.audio-V3-ndk",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
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/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc
index 1521897450..bfe4c6f41a 100644
--- a/system/btif/src/btif_dm.cc
+++ b/system/btif/src/btif_dm.cc
@@ -602,11 +602,6 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr,
GetInterfaceToProfiles()->events->invoke_bond_state_changed_cb(
status, bd_addr, state, pairing_cb.fail_reason);
- int dev_type;
- if (!btif_get_device_type(bd_addr, &dev_type)) {
- dev_type = BT_DEVICE_TYPE_BREDR;
- }
-
if ((state == BT_BOND_STATE_NONE) && (pairing_cb.bd_addr != bd_addr)
&& is_bonding_or_sdp()) {
LOG_WARN("Ignoring bond state changed for unexpected device: %s pairing: %s",
diff --git a/system/build/Android.bp b/system/build/Android.bp
index 95b20a2ec7..52a5850179 100644
--- a/system/build/Android.bp
+++ b/system/build/Android.bp
@@ -19,7 +19,6 @@ cc_defaults {
// struct BT_HDR is defined as a variable-size header in a struct.
"-Wno-gnu-variable-sized-type-not-at-end",
],
- c_std: "c99",
product_variables: {
debuggable: {
cflags: [
@@ -57,7 +56,6 @@ cc_defaults {
"libbt_shim_bridge",
"libbt_shim_ffi",
],
- cpp_std: "c++17",
min_sdk_version: "current",
}
@@ -71,7 +69,6 @@ cc_defaults {
],
static_libs: [
"libbt-common",
- "libbt-protos-lite",
"libcutils",
"libgmock",
"libosi",
@@ -86,28 +83,11 @@ cc_defaults {
}
cc_defaults {
- name: "fluoride_basic_defaults",
- defaults: [
- "fluoride_defaults",
- ],
- apex_available: [
- "//apex_available:platform",
- "com.android.btservices",
- ],
- static_libs: [
- "libbt-protos-lite",
- "libflatbuffers-cpp",
- "libprotobuf-cpp-lite",
- ],
-}
-
-cc_defaults {
name: "fluoride_defaults",
defaults: [
"fluoride_defaults_fuzzable",
],
static_libs: [
- "libbluetooth_gd",
"libstatslog_bt",
],
target: {
diff --git a/system/common/Android.bp b/system/common/Android.bp
index 3c6a803dca..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"],
@@ -40,6 +48,9 @@ cc_library_static {
"libcrypto",
"libcutils",
],
+ apex_available: [
+ "com.android.btservices",
+ ],
min_sdk_version: "Tiramisu",
}
@@ -85,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 59b7a3d9b4..738db4f73f 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",
@@ -28,6 +28,9 @@ cc_library_static {
"src/esco_parameters.cc",
"src/interop.cc",
],
+ apex_available: [
+ "com.android.btservices",
+ ],
min_sdk_version: "Tiramisu",
}
@@ -50,6 +53,7 @@ cc_test {
],
static_libs: [
"libbluetooth-types",
+ "libbluetooth_gd",
"libbtcore",
"libbtdevice",
"libchrome",
diff --git a/system/device/fuzzer/Android.bp b/system/device/fuzzer/Android.bp
index 08aeaa971a..1f5193d948 100644
--- a/system/device/fuzzer/Android.bp
+++ b/system/device/fuzzer/Android.bp
@@ -35,6 +35,7 @@ cc_fuzz {
],
static_libs: [
"libbluetooth-types",
+ "libbluetooth_gd",
"libbtcore",
"libbtdevice",
"libchrome",
diff --git a/system/doc/btsnoop_net.md b/system/doc/btsnoop_net.md
deleted file mode 100644
index 6964a9add6..0000000000
--- a/system/doc/btsnoop_net.md
+++ /dev/null
@@ -1,16 +0,0 @@
-btsnoop_net
-====
-btsnoop_net exposes Bluetooth snoop logs over a local TCP socket which enables
-real-time debugging of HCI data with hcidump.
-
-This feature is enabled by enabling "Enable Bluetooth HCI snoop log" in the
-Developer options and setting BT_NET_DEBUG flag to TRUE in the btsnoop_net.cc.
-Once it has been enabled and the stack restarted, the stack will listen for
-incoming TCP connections on port 8872.
-
-To use this feature with btmon on a Linux host, you can run:
-
-```
- $ adb forward tcp:8872 tcp:8872
- $ nc localhost 8872 | btmon -P -r /dev/stdin
-```
diff --git a/system/doc/log_tags.md b/system/doc/log_tags.md
deleted file mode 100644
index fe6a3e4dba..0000000000
--- a/system/doc/log_tags.md
+++ /dev/null
@@ -1,57 +0,0 @@
-Log Tags
-===
-This document lists all of the log tags used by the Bluetooth stack.
-
-* audio_a2dp_hw
-* BTA_AG_CO:
-* bta_sys_main
-* bt_btif
-* bt_btif_config
-* bt_btif_config_transcode
-* bt_classic_peer
-* bte_conf
-* BtGatt.btif
-* BtGatt.btif_test
-* bt_hci
-* bt_hci_h4
-* bt_hci_inject
-* bt_hci_mct
-* bt_hci_packet_fragmenter
-* BTIF_AV
-* BTIF_CORE
-* BTIF_HF
-* BTIF_HF_CLIENT
-* BTIF_HH
-* BTIF_HL
-* BTIF-MEDIA
-* BTIF_PAN
-* BTIF_QUEUE
-* BTIF_RC
-* BTIF_SM
-* btif_sock
-* BTIF_SOCK
-* btif_sock_rfcomm
-* btif_sock_sco
-* BTIF_SOCK_SDP
-* BTIF_STORAGE
-* BTIF_UTIL
-* BTLD
-* bt_module
-* bt_osi_alarm
-* bt_osi_config
-* bt_osi_data_dispatcher
-* bt_osi_reactor
-* bt_osi_socket
-* bt_profile_manager
-* bt_sdp_client
-* btsnoop
-* btsnoop_net
-* bt_stack_config
-* bt_stack_manager
-* bt_task
-* btu_task
-* BT_UTILS
-* bt_vendor
-* osi_future
-* osi_semaphore
-* osi_thread
diff --git a/system/doc/network_ports.md b/system/doc/network_ports.md
deleted file mode 100644
index 03e138e0df..0000000000
--- a/system/doc/network_ports.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Network Ports
-===
-This document lists all of the network ports used by the bluetooth stack.
-It should be used as a reference and as a mechanism to avoid port
-namespace conflicts.
-
-* TCP 8872 (hci/src/btsnoop_net.cc) - read live btsnoop logs
-* TCP 8873 (hci/src/hci_inject.cc) - inject HCI packets into HCI stream
diff --git a/system/doc/properties.md b/system/doc/properties.md
deleted file mode 100644
index c4ab97c018..0000000000
--- a/system/doc/properties.md
+++ /dev/null
@@ -1,20 +0,0 @@
-Properties
-===
-This document describes all of the Android properties used by the Bluetooth
-stack.
-
-Please keep the following list in alphabetical order.
-
-* ``` bluetooth.enable_timeout_ms ```
- Maximum amount of time Bluetooth can take to start-up, upload firmware etc.
- Used in hci/src/hci_layer.cc, default 8000.
-
-### TODO: write descriptions of what each property means and how
-it's used.
-
-* ``` debug.sys.noschedgroups ```
-* ``` persist.service.bdroid.bdaddr ```
-* ``` ro.bluetooth.hfp.ver ```
-* ``` ro.bt.bdaddr_path ```
-* ``` ro.product.model ```
-* ``` service.brcm.bt.oob ```
diff --git a/system/doc/pts_guide.md b/system/doc/pts_guide.md
deleted file mode 100644
index 1e13b9d07b..0000000000
--- a/system/doc/pts_guide.md
+++ /dev/null
@@ -1,43 +0,0 @@
-# Fluoride Bluetooth Profile Tuning Suite (PTS) Test Mode
-
-This document provides commands to enable PTS test mode for Fluoride stack. We
-need special handling for some test cases as they are not applicable for the
-Fluoride stack.
-
-## PTS Test Mode system property
-
-Profile services in packages/apps/Bluetooth uses system property
-`persist.bluetooth.pts` to check if the PTS test mode is enabled. To enable it:
-
-```sh
-adb shell setprop persist.bluetooth.pts true
-```
-
-To disable it:
-
-```sh
-adb shell setprop persist.bluetooth.pts false
-```
-
-### Current use case
-
-- In `newavrcp`, we send active player update to remote device only in PTS test
- mode (AVRCP/TG/MPS/BV-05-C AVRCP/TG/MPS/BV-07-C).
-
-## PTS Helpers in stack config
-
-Native stack also requires some special handling, and the config is stored in
-`conf/bt_stack.conf`. To enable a flag, uncomment the corresponding line and
-push the config file to `/etc/bluetooth/` in IUT.
-
-### Current use case
-
-- `PTS_SecurePairOnly` enables secure connections only mode.
-- `PTS_DisableConnUpdates` disables LE Connection updates.
-- `PTS_DisableSDPOnLEPair` disables BR/EDR discovery after LE pairing to avoid
- cross key derivation errors.
-- `PTS_SmpOptions` sets SMP Pair options (formatted as hex bytes) `auth, io,
- ikey, rkey, ksize`.
-- `PTS_AvrcpTest` enables AVRCP test mode. The UID is set to 0xffffffffffffffff
- in `TrackChangedNotificationResponse` (AVRCP/TG/NFY/BV-04-C).
-- `PTS_SmpFailureCase` enables handling for various SMP failure cases.
diff --git a/system/doc/supported_features.md b/system/doc/supported_features.md
deleted file mode 100644
index 50ca84d027..0000000000
--- a/system/doc/supported_features.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Fluoride 1.1
-
-Declaration ID: [D024527](https://www.bluetooth.org/tpg/QLI_viewQDL.cfm?qid=24527)
-Qualified Design ID: 83953
-
-Protocol / Profile | Version | Roles
--------------------+---------+-------
-L2CAP | 4.2 | Initiator, Acceptor, LE Central, LE Peripheral
-SDP | 4.2 | Server, Client
-GAP | 4.2 | BR/EDR, LE Central, LE Periperhal, LE Observer, LE Broadcaster
-GATT | 4.2 | Client, Server; LE and BR/EDR
-ATT | 4.2 | Client, Server; LE and BR/EDR
-SM | 4.2 | Central (Initiator), Peripheral (Responder)
-AVCTP | 1.4 | Controller, Target
-AVDTP | 1.2 | Source, Initiator, Acceptor
-BNEP | 1.0 |
-GAVDP | 1.2 | Initiator, Acceptor
-RFCOMM | 1.2 |
-SPP | 1.2 | A, B
diff --git a/system/gd/Android.bp b/system/gd/Android.bp
index cdf6ae2c7d..70e52fe37e 100644
--- a/system/gd/Android.bp
+++ b/system/gd/Android.bp
@@ -30,7 +30,6 @@ cc_defaults {
enabled: false,
},
},
- cpp_std: "c++17",
cflags: [
"-DEXPORT_SYMBOL=__attribute__((visibility(\"default\")))",
"-DGOOGLE_PROTOBUF_NO_RTTI",
@@ -38,7 +37,6 @@ cc_defaults {
"-Wno-unused-result",
"-fvisibility=hidden",
],
- c_std: "c99",
header_libs: ["jni_headers"],
}
@@ -164,6 +162,9 @@ cc_defaults {
"libcrypto",
"libflatbuffers-cpp",
],
+ export_shared_lib_headers: [
+ "libflatbuffers-cpp",
+ ],
whole_static_libs: [
"libc++fs",
],
@@ -470,7 +471,6 @@ cc_defaults {
],
shared_libs: [
"libcrypto",
- "libflatbuffers-cpp",
"libgrpc++",
"libgrpc_wrap",
],
diff --git a/system/gd/btaa/activity_attribution.h b/system/gd/btaa/activity_attribution.h
index 93f5549dd3..7ad4ad42b3 100644
--- a/system/gd/btaa/activity_attribution.h
+++ b/system/gd/btaa/activity_attribution.h
@@ -36,17 +36,6 @@ struct BtaaAggregationEntry {
CreationTime creation_time;
};
-class ActivityAttributionCallback {
- public:
- virtual ~ActivityAttributionCallback() = default;
-
- // Callback when Bluetooth woke up the system
- virtual void OnWakeup(const Activity activity, const hci::Address& address) = 0;
-
- // Callback when Bluetooth activity logs are ready to be moved
- virtual void OnActivityLogsReady(const std::vector<BtaaAggregationEntry> logs) = 0;
-};
-
class ActivityAttribution : public bluetooth::Module {
public:
ActivityAttribution() = default;
@@ -59,7 +48,6 @@ class ActivityAttribution : public bluetooth::Module {
void OnWakelockAcquired();
void OnWakelockReleased();
void OnWakeup();
- void RegisterActivityAttributionCallback(ActivityAttributionCallback* callback);
void NotifyActivityAttributionInfo(int uid, const std::string& package_name, const std::string& device_address);
static const ModuleFactory Factory;
diff --git a/system/gd/btaa/android/activity_attribution.cc b/system/gd/btaa/android/activity_attribution.cc
index 79e0cea62d..e7a15bd9d6 100644
--- a/system/gd/btaa/android/activity_attribution.cc
+++ b/system/gd/btaa/android/activity_attribution.cc
@@ -158,10 +158,6 @@ struct ActivityAttribution::impl {
attribution_processor_.OnWakeup();
}
- void register_callback(ActivityAttributionCallback* callback) {
- callback_ = callback;
- }
-
void notify_activity_attribution_info(int uid, const std::string& package_name, const std::string& device_address) {
attribution_processor_.NotifyActivityAttributionInfo(uid, package_name, device_address);
}
@@ -171,7 +167,6 @@ struct ActivityAttribution::impl {
attribution_processor_.Dump(std::move(promise), fb_builder);
}
- ActivityAttributionCallback* callback_;
AttributionProcessor attribution_processor_;
HciProcessor hci_processor_;
WakelockProcessor wakelock_processor_;
@@ -213,10 +208,6 @@ void ActivityAttribution::OnWakeup() {
CallOn(pimpl_.get(), &impl::on_wakeup);
}
-void ActivityAttribution::RegisterActivityAttributionCallback(ActivityAttributionCallback* callback) {
- CallOn(pimpl_.get(), &impl::register_callback, callback);
-}
-
void ActivityAttribution::NotifyActivityAttributionInfo(
int uid, const std::string& package_name, const std::string& device_address) {
CallOn(pimpl_.get(), &impl::notify_activity_attribution_info, uid, package_name, device_address);
diff --git a/system/gd/btaa/host/activity_attribution.cc b/system/gd/btaa/host/activity_attribution.cc
index ec02daf108..20c7ac76cc 100644
--- a/system/gd/btaa/host/activity_attribution.cc
+++ b/system/gd/btaa/host/activity_attribution.cc
@@ -29,8 +29,6 @@ void ActivityAttribution::OnWakelockReleased() {}
void ActivityAttribution::OnWakeup() {}
-void ActivityAttribution::RegisterActivityAttributionCallback(ActivityAttributionCallback* callback) {}
-
void ActivityAttribution::NotifyActivityAttributionInfo(
int uid, const std::string& package_name, const std::string& device_address) {}
diff --git a/system/gd/btaa/linux/activity_attribution.cc b/system/gd/btaa/linux/activity_attribution.cc
index c4a4eb0aab..c39186750a 100644
--- a/system/gd/btaa/linux/activity_attribution.cc
+++ b/system/gd/btaa/linux/activity_attribution.cc
@@ -26,14 +26,10 @@ struct ActivityAttribution::impl {
impl(ActivityAttribution* module) {}
void on_hci_packet(hal::HciPacket packet, hal::SnoopLogger::PacketType type, uint16_t length) {}
-
- void register_callback(ActivityAttributionCallback* callback) {}
};
void ActivityAttribution::Capture(const hal::HciPacket& packet, hal::SnoopLogger::PacketType type) {}
-void ActivityAttribution::RegisterActivityAttributionCallback(ActivityAttributionCallback* callback) {}
-
void ActivityAttribution::NotifyActivityAttributionInfo(
int uid, const std::string& package_name, const std::string& device_address) {}
diff --git a/system/gd/dumpsys/bundler/Android.bp b/system/gd/dumpsys/bundler/Android.bp
index f2f346a9ec..64059976bb 100644
--- a/system/gd/dumpsys/bundler/Android.bp
+++ b/system/gd/dumpsys/bundler/Android.bp
@@ -49,7 +49,6 @@ genrule {
cc_defaults {
name: "bluetooth_flatbuffer_bundler_defaults",
defaults: ["bluetooth_cflags"],
- cpp_std: "c++17",
generated_headers: [
"BluetoothGeneratedBundlerSchema_h_bfbs",
],
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/Android.bp b/system/gd/rust/topshim/Android.bp
index 157f5dbd62..5f3e6e8f79 100644
--- a/system/gd/rust/topshim/Android.bp
+++ b/system/gd/rust/topshim/Android.bp
@@ -111,7 +111,7 @@ rust_bindgen {
crate_name: "bt_topshim_wrapper_bindgen",
source_stem: "bindings",
defaults: ["bluetooth_cflags"],
- cpp_std: "c++17",
+ c_std: "",
host_supported: true,
bindgen_flags: [
"--allowlist-function=bt_.*",
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 cf60675ee3..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",
@@ -32,6 +32,9 @@ cc_library_static {
"packages/modules/Bluetooth/system/stack/include",
"system/libhwbinder/include",
],
+ apex_available: [
+ "com.android.btservices",
+ ],
host_supported: true,
min_sdk_version: "Tiramisu",
}
@@ -42,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/include/hardware/bt_activity_attribution.h b/system/include/hardware/bt_activity_attribution.h
index a9c37c4751..c8f56bc61a 100644
--- a/system/include/hardware/bt_activity_attribution.h
+++ b/system/include/hardware/bt_activity_attribution.h
@@ -24,51 +24,10 @@
namespace bluetooth {
namespace activity_attribution {
-class ActivityAttributionCallbacks {
- public:
- enum class Activity : uint8_t {
- UNKNOWN = 0,
- ACL,
- ADVERTISE,
- CONNECT,
- CONTROL,
- HFP,
- ISO,
- SCAN,
- VENDOR,
- };
-
- struct BtaaAggregationEntry {
- RawAddress address;
- Activity activity;
- uint16_t wakeup_count;
- uint32_t byte_count;
- uint32_t wakelock_duration;
- };
-
- virtual ~ActivityAttributionCallbacks() = default;
-
- /** Callback when Bluetooth woke up the system */
- virtual void OnWakeup(const Activity activity, const RawAddress& address) = 0;
-
- /** Callback when Bluetooth activity logs are ready to be moved */
- virtual void OnActivityLogsReady(
- const std::vector<BtaaAggregationEntry> logs) = 0;
-};
-
class ActivityAttributionInterface {
public:
virtual ~ActivityAttributionInterface() = default;
- /** Init the interface. */
- virtual void Init(void) = 0;
-
- /** Register JNI callbacks with the interface. */
- virtual void RegisterCallbacks(ActivityAttributionCallbacks* callbacks) = 0;
-
- /** Closes the interface. */
- virtual void Cleanup(void) = 0;
-
/** Notify the UID and package name of the app, and the address of associated
* active device */
virtual void NotifyActivityAttributionInfo(
diff --git a/system/main/Android.bp b/system/main/Android.bp
index d84e98b03e..7db09bbab3 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",
@@ -52,8 +52,12 @@ cc_library_static {
"BluetoothGeneratedDumpsysDataSchema_h",
"BluetoothGeneratedPackets_h",
],
+ apex_available: [
+ "com.android.btservices",
+ ],
host_supported: true,
min_sdk_version: "Tiramisu",
+ static_libs: ["libbluetooth_gd"],
}
cc_library {
@@ -63,7 +67,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: [
@@ -143,7 +147,6 @@ cc_library_static {
"-DBUILDCFG",
],
shared_libs: [
- "libflatbuffers-cpp",
],
whole_static_libs: [
"libbluetooth_gd", // Gabeldorsche
@@ -202,8 +205,8 @@ cc_test {
],
static_libs: [
"libbluetooth-dumpsys",
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libbtdevice",
"libchrome",
"libevent",
diff --git a/system/main/shim/activity_attribution.cc b/system/main/shim/activity_attribution.cc
index 4695309b74..12eed9de56 100644
--- a/system/main/shim/activity_attribution.cc
+++ b/system/main/shim/activity_attribution.cc
@@ -23,9 +23,7 @@
#include "main/shim/entry.h"
#include "types/raw_address.h"
-class ActivityAttributionInterfaceImpl
- : public ActivityAttributionInterface,
- public bluetooth::activity_attribution::ActivityAttributionCallback {
+class ActivityAttributionInterfaceImpl : public ActivityAttributionInterface {
public:
~ActivityAttributionInterfaceImpl() override = default;
@@ -35,17 +33,6 @@ class ActivityAttributionInterfaceImpl
return instance;
}
- void Init() override {
- bluetooth::shim::GetActivityAttribution()
- ->RegisterActivityAttributionCallback(this);
- }
-
- void RegisterCallbacks(ActivityAttributionCallbacks* callbacks) override {
- this->callbacks = callbacks;
- }
-
- void Cleanup(void) override{};
-
void NotifyActivityAttributionInfo(
int uid, const std::string& package_name,
const std::string& device_address) override {
@@ -53,44 +40,12 @@ class ActivityAttributionInterfaceImpl
uid, package_name, device_address);
}
- void OnWakeup(const Activity activity,
- const bluetooth::hci::Address& address) override {
- do_in_jni_thread(
- FROM_HERE, base::Bind(&ActivityAttributionCallbacks::OnWakeup,
- base::Unretained(callbacks),
- (ActivityAttributionCallbacks::Activity)activity,
- bluetooth::ToRawAddress(address)));
- }
-
- void OnActivityLogsReady(
- const std::vector<BtaaAggregationEntry> logs) override {
- std::vector<ActivityAttributionCallbacks::BtaaAggregationEntry>
- callback_logs;
- for (auto& it : logs) {
- ActivityAttributionCallbacks::BtaaAggregationEntry entry{
- bluetooth::ToRawAddress(it.address),
- (ActivityAttributionCallbacks::Activity)it.activity, it.wakeup_count,
- it.byte_count, it.wakelock_duration_ms};
- callback_logs.push_back(entry);
- }
- do_in_jni_thread(
- FROM_HERE,
- base::Bind(&ActivityAttributionCallbacks::OnActivityLogsReady,
- base::Unretained(callbacks), callback_logs));
- }
-
private:
// Private constructor to prevent construction.
ActivityAttributionInterfaceImpl() {}
-
- ActivityAttributionCallbacks* callbacks;
};
ActivityAttributionInterface*
bluetooth::shim::get_activity_attribution_instance() {
return ActivityAttributionInterfaceImpl::GetInstance();
}
-
-void bluetooth::shim::init_activity_attribution() {
- bluetooth::shim::get_activity_attribution_instance()->Init();
-}
diff --git a/system/main/shim/activity_attribution.h b/system/main/shim/activity_attribution.h
index 00d8099971..0f1253415e 100644
--- a/system/main/shim/activity_attribution.h
+++ b/system/main/shim/activity_attribution.h
@@ -28,7 +28,5 @@ namespace shim {
ActivityAttributionInterface* get_activity_attribution_instance();
-void init_activity_attribution();
-
} // namespace shim
} // namespace bluetooth
diff --git a/system/main/shim/stack.cc b/system/main/shim/stack.cc
index 40dc243024..017b954168 100644
--- a/system/main/shim/stack.cc
+++ b/system/main/shim/stack.cc
@@ -148,9 +148,6 @@ void Stack::StartEverything() {
!common::init_flags::gd_core_is_enabled()) {
L2CA_UseLegacySecurityModule();
}
- if (common::init_flags::btaa_hci_is_enabled()) {
- bluetooth::shim::init_activity_attribution();
- }
}
void Stack::Start(ModuleList* modules) {
diff --git a/system/main/test/main_shim_test.cc b/system/main/test/main_shim_test.cc
index fcaf32b4c5..83c6f4350f 100644
--- a/system/main/test/main_shim_test.cc
+++ b/system/main/test/main_shim_test.cc
@@ -345,8 +345,6 @@ class MockLeAclConnection
namespace bluetooth {
namespace shim {
-void init_activity_attribution() {}
-
namespace testing {
extern os::Handler* mock_handler_;
diff --git a/system/osi/Android.bp b/system/osi/Android.bp
index da4f9cf2e1..917fe1280a 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
@@ -159,8 +159,8 @@ cc_test {
"test",
],
static_libs: [
+ "libbluetooth_gd",
"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/profile/avrcp/Android.bp b/system/profile/avrcp/Android.bp
index 8bb0912c73..19c5c1d3de 100644
--- a/system/profile/avrcp/Android.bp
+++ b/system/profile/avrcp/Android.bp
@@ -70,6 +70,7 @@ cc_test {
"lib-bt-packets-avrcp",
"lib-bt-packets-base",
"libbase",
+ "libbluetooth_gd",
"libbtdevice",
"libchrome",
"libcutils",
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 97619c7269..197383a7ad 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",
@@ -292,6 +292,7 @@ cc_library_static {
],
static_libs: [
"libbluetooth_core_rs",
+ "libbluetooth_gd",
"libbt-hci",
],
shared_libs: [
@@ -643,7 +644,7 @@ cc_test {
"libz",
],
static_libs: [
- "android.hardware.audio.common-V1-ndk",
+ "android.hardware.audio.common-V2-ndk",
"android.hardware.bluetooth.a2dp@1.0",
"android.hardware.bluetooth.audio-V3-ndk",
"android.hardware.bluetooth@1.0",
@@ -660,7 +661,6 @@ cc_test {
"libbt-bta-core",
"libbt-common",
"libbt-hci",
- "libbt-protos-lite",
"libbt-sbc-decoder",
"libbt-sbc-encoder",
"libbt-stack",
@@ -738,11 +738,10 @@ cc_test {
"libcutils",
],
static_libs: [
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libevent",
- "libflatbuffers-cpp",
"libgmock",
"liblog",
"libosi",
@@ -816,9 +815,9 @@ cc_test {
"libcutils",
],
static_libs: [
+ "libbluetooth_gd",
"libchrome",
"libevent",
- "libflatbuffers-cpp",
"libgmock",
"liblog",
"libosi",
@@ -883,6 +882,7 @@ cc_test {
],
static_libs: [
"libbluetooth-types",
+ "libbluetooth_gd",
"libbt-common",
"libchrome",
"libevent",
@@ -931,8 +931,8 @@ cc_test {
"libcutils",
],
static_libs: [
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libevent",
"libgmock",
@@ -996,8 +996,8 @@ cc_test {
"libcutils",
],
static_libs: [
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libevent",
"liblog",
@@ -1103,8 +1103,8 @@ cc_test {
],
static_libs: [
"libFraunhoferAAC",
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libbt-sbc-decoder",
"libbt-sbc-encoder",
"libchrome",
@@ -1156,7 +1156,6 @@ cc_test {
],
static_libs: [
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"liblog",
"libosi",
@@ -1211,8 +1210,8 @@ cc_test {
"libcutils",
],
static_libs: [
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libevent",
"libgmock",
@@ -1318,8 +1317,8 @@ cc_test {
"libcutils",
],
static_libs: [
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libchrome",
"libevent",
"libgmock",
@@ -1417,28 +1416,28 @@ 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: [
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libbt-sbc-decoder",
"libbt-sbc-encoder",
"libbtdevice",
"libchrome",
"libevent",
- "libflatbuffers-cpp",
"libgmock",
"liblc3",
"liblog",
@@ -1486,7 +1485,6 @@ cc_test {
],
static_libs: [
"libbt-common",
- "libbt-protos-lite",
"libbtdevice",
"libbte",
"libchrome",
@@ -1542,7 +1540,6 @@ cc_test {
],
static_libs: [
"libbt-common",
- "libbt-protos-lite",
"libbtdevice",
"libbte",
"libchrome",
@@ -1613,12 +1610,11 @@ cc_test {
"test/stack_btu_test.cc",
],
static_libs: [
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libbtdevice",
"libchrome",
"libevent",
- "libflatbuffers-cpp",
"libgmock",
"liblog",
"libosi",
@@ -1695,12 +1691,11 @@ cc_test {
"test/gatt/stack_gatt_test.cc",
],
static_libs: [
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libbtdevice",
"libchrome",
"libevent",
- "libflatbuffers-cpp",
"libgmock",
"liblog",
"libosi",
@@ -1777,12 +1772,11 @@ cc_test {
"test/stack_l2cap_test.cc",
],
static_libs: [
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libbtdevice",
"libchrome",
"libevent",
- "libflatbuffers-cpp",
"libgmock",
"liblog",
"libosi",
@@ -1863,12 +1857,11 @@ cc_test {
"test/stack_acl_test.cc",
],
static_libs: [
+ "libbluetooth_gd",
"libbt-common",
- "libbt-protos-lite",
"libbtdevice",
"libchrome",
"libevent",
- "libflatbuffers-cpp",
"libgmock",
"liblog",
"libosi",
@@ -1932,6 +1925,7 @@ cc_test {
],
static_libs: [
"libbluetooth-types",
+ "libbluetooth_gd",
"libbt-common",
"libchrome",
"libgmock",
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/l2cap/l2c_csm.cc b/system/stack/l2cap/l2c_csm.cc
index 32c8ab9a55..44c4c99076 100644
--- a/system/stack/l2cap/l2c_csm.cc
+++ b/system/stack/l2cap/l2c_csm.cc
@@ -100,9 +100,13 @@ static void l2c_csm_indicate_connection_open(tL2C_CCB* p_ccb) {
if (p_ccb->connection_initiator == L2CAP_INITIATOR_LOCAL) {
(*p_ccb->p_rcb->api.pL2CA_ConnectCfm_Cb)(p_ccb->local_cid, L2CAP_CONN_OK);
} else {
- (*p_ccb->p_rcb->api.pL2CA_ConnectInd_Cb)(
- p_ccb->p_lcb->remote_bd_addr, p_ccb->local_cid, p_ccb->p_rcb->psm,
- p_ccb->remote_id);
+ if (*p_ccb->p_rcb->api.pL2CA_ConnectInd_Cb) {
+ (*p_ccb->p_rcb->api.pL2CA_ConnectInd_Cb)(
+ p_ccb->p_lcb->remote_bd_addr, p_ccb->local_cid, p_ccb->p_rcb->psm,
+ p_ccb->remote_id);
+ } else {
+ LOG_WARN("pL2CA_ConnectInd_Cb is null");
+ }
}
if (p_ccb->chnl_state == CST_OPEN && !p_ccb->p_lcb->is_transport_ble()) {
(*p_ccb->p_rcb->api.pL2CA_ConfigCfm_Cb)(
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_bta_dm_act.cc b/system/test/mock/mock_bta_dm_act.cc
index 0cf293fa1d..42365fbd72 100644
--- a/system/test/mock/mock_bta_dm_act.cc
+++ b/system/test/mock/mock_bta_dm_act.cc
@@ -80,7 +80,6 @@ struct bta_dm_free_sdp_db bta_dm_free_sdp_db;
struct bta_dm_inq_cmpl bta_dm_inq_cmpl;
struct bta_dm_is_search_request_queued bta_dm_is_search_request_queued;
struct bta_dm_pin_reply bta_dm_pin_reply;
-struct bta_dm_proc_open_evt bta_dm_proc_open_evt;
struct bta_dm_process_remove_device bta_dm_process_remove_device;
struct bta_dm_queue_disc bta_dm_queue_disc;
struct bta_dm_queue_search bta_dm_queue_search;
@@ -295,10 +294,6 @@ void bta_dm_pin_reply(std::unique_ptr<tBTA_DM_API_PIN_REPLY> msg) {
inc_func_call_count(__func__);
test::mock::bta_dm_act::bta_dm_pin_reply(std::move(msg));
}
-void bta_dm_proc_open_evt(tBTA_GATTC_OPEN* p_data) {
- inc_func_call_count(__func__);
- test::mock::bta_dm_act::bta_dm_proc_open_evt(p_data);
-}
void bta_dm_process_remove_device(const RawAddress& bd_addr) {
inc_func_call_count(__func__);
test::mock::bta_dm_act::bta_dm_process_remove_device(bd_addr);
diff --git a/system/test/mock/mock_bta_dm_act.h b/system/test/mock/mock_bta_dm_act.h
index 661a7537d5..e58a58d7c2 100644
--- a/system/test/mock/mock_bta_dm_act.h
+++ b/system/test/mock/mock_bta_dm_act.h
@@ -585,16 +585,6 @@ struct bta_dm_pin_reply {
};
extern struct bta_dm_pin_reply bta_dm_pin_reply;
-// Name: bta_dm_proc_open_evt
-// Params: tBTA_GATTC_OPEN* p_data
-// Return: void
-struct bta_dm_proc_open_evt {
- std::function<void(tBTA_GATTC_OPEN* p_data)> body{
- [](tBTA_GATTC_OPEN* p_data) {}};
- void operator()(tBTA_GATTC_OPEN* p_data) { body(p_data); };
-};
-extern struct bta_dm_proc_open_evt bta_dm_proc_open_evt;
-
// Name: bta_dm_process_remove_device
// Params: const RawAddress& bd_addr
// Return: void
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/system/test/mock/mock_main_shim_activity_attribution.cc b/system/test/mock/mock_main_shim_activity_attribution.cc
index 3b67f5aac9..83cfaa3872 100644
--- a/system/test/mock/mock_main_shim_activity_attribution.cc
+++ b/system/test/mock/mock_main_shim_activity_attribution.cc
@@ -36,6 +36,3 @@ bluetooth::shim::get_activity_attribution_instance() {
inc_func_call_count(__func__);
return nullptr;
}
-void bluetooth::shim::init_activity_attribution() {
- inc_func_call_count(__func__);
-}
diff --git a/system/test/run_benchmarks.sh b/system/test/run_benchmarks.sh
deleted file mode 100755
index 3ca1d0999b..0000000000
--- a/system/test/run_benchmarks.sh
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/bin/sh
-# A utility script that runs benchmark on Android device
-#
-# Note: Only one Android device can be connected when running this script
-#
-# Example usage:
-# $ cd packages/modules/Bluetooth/system
-# $ ./test/run_benchmarks.sh bluetooth_benchmark_example
-
-known_benchmarks=(
- bluetooth_benchmark_thread_performance
- bluetooth_benchmark_timer_performance
-)
-
-usage() {
- binary="$(basename "$0")"
- echo "Usage: ${binary} --help"
- echo " ${binary} [-i <iterations>] [-s <specific device>] [--all] [<benchmark name>[.<filter>] ...] [--<arg> ...]"
- echo
- echo "Unknown long arguments are passed to the benchmark."
- echo
- echo "Known benchmark names:"
-
- for name in "${known_benchmarks[@]}"
- do
- echo " ${name}"
- done
-}
-
-iterations=1
-device=
-benchmarks=()
-benchmark_args=()
-while [ $# -gt 0 ]
-do
- case "$1" in
- -h|--help)
- usage
- exit 0
- ;;
- -i)
- shift
- if [ $# -eq 0 ]; then
- echo "error: number of iterations expected" 1>&2
- usage
- exit 2
- fi
- iterations=$(( $1 ))
- shift
- ;;
- -s)
- shift
- if [ $# -eq 0 ]; then
- echo "error: no device specified" 1>&2
- usage
- exit 2
- fi
- device="$1"
- shift
- ;;
- --all)
- benchmarks+=( "${known_benchmarks[@]}" )
- shift
- ;;
- --*)
- benchmark_args+=( "$1" )
- shift
- ;;
- *)
- benchmarks+=( "$1" )
- shift
- ;;
- esac
-done
-
-if [ "${#benchmarks[@]}" -eq 0 ]; then
- benchmarks+=( "${known_benchmarks[@]}" )
-fi
-
-adb=( "adb" )
-if [ -n "${device}" ]; then
- adb+=( "-s" "${device}" )
-fi
-
-source ${ANDROID_BUILD_TOP}/build/envsetup.sh
-target_arch=$(gettargetarch)
-
-failed_benchmarks=()
-for spec in "${benchmarks[@]}"
-do
- name="${spec%%.*}"
- if [[ $target_arch == *"64"* ]]; then
- binary="/data/benchmarktest64/${name}/${name}"
- else
- binary="/data/benchmarktest/${name}/${name}"
- fi
-
- push_command=( "${adb[@]}" push {"${ANDROID_PRODUCT_OUT}",}"${binary}" )
- benchmark_command=( "${adb[@]}" shell "${binary}" )
- if [ "${name}" != "${spec}" ]; then
- filter="${spec#*.}"
- benchmark_command+=( "--benchmark_filter=${filter}" )
- fi
- benchmark_command+=( "${benchmark_args[@]}" )
-
- echo "--- ${name} ---"
- echo "pushing..."
- "${push_command[@]}"
- echo "running..."
- failed_count=0
- for i in $(seq 1 ${iterations})
- do
- "${benchmark_command[@]}" || failed_count=$(( $failed_count + 1 ))
- done
-
- if [ $failed_count != 0 ]; then
- failed_benchmarks+=( "${name} ${failed_count}/${iterations}" )
- fi
-done
-
-if [ "${#failed_benchmarks[@]}" -ne 0 ]; then
- for failed_benchmark in "${failed_benchmarks[@]}"
- do
- echo "!!! FAILED TEST: ${failed_benchmark} !!!"
- done
- exit 1
-fi
-
-exit 0
diff --git a/system/test/run_host_unit_tests.py b/system/test/run_host_unit_tests.py
deleted file mode 100755
index 5f70325fae..0000000000
--- a/system/test/run_host_unit_tests.py
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2017, 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.
-import sys
-import subprocess
-import os
-import argparse
-
-# Registered host based unit tests
-# Must have 'host_supported: true'
-HOST_TESTS = [
- 'bluetooth_test_common',
- 'bluetoothtbd_test',
- 'net_test_avrcp',
- 'net_test_btcore',
- 'net_test_types',
- 'net_test_btm_iso',
- 'net_test_btpackets',
-]
-
-SOONG_UI_BASH = 'build/soong/soong_ui.bash'
-
-
-def str2bool(argument, default=False):
- """ Convert a string to a booleen value. """
- argument = str(argument)
- if argument.lower() in ['0', 'f', 'false', 'off', 'no', 'n']:
- return False
- elif argument.lower() in ['1', 't', 'true', 'on', 'yes', 'y']:
- return True
- return default
-
-
-def check_dir_exists(dir, dirname):
- if not os.path.isdir(dir):
- print "Couldn't find %s (%s)!" % (dirname, dir)
- sys.exit(0)
-
-
-def get_output_from_command(cmd):
- try:
- return subprocess.check_output(cmd).strip()
- except subprocess.CalledProcessError as e:
- print 'Failed to call {cmd}, return code {code}'.format(cmd=cmd, code=e.returncode)
- print e
- return None
-
-
-def get_android_root_or_die():
- value = os.environ.get('ANDROID_BUILD_TOP')
- if not value:
- # Try to find build/soong/soong_ui.bash upwards until root directory
- current_path = os.path.abspath(os.getcwd())
- while current_path and os.path.isdir(current_path):
- soong_ui_bash_path = os.path.join(current_path, SOONG_UI_BASH)
- if os.path.isfile(soong_ui_bash_path):
- # Use value returned from Soong UI instead in case definition to TOP
- # changes in the future
- value = get_output_from_command((soong_ui_bash_path, '--dumpvar-mode', '--abs', 'TOP'))
- break
- parent_path = os.path.abspath(os.path.join(current_path, os.pardir))
- if parent_path == current_path:
- current_path = None
- else:
- current_path = parent_path
- if not value:
- print 'Cannot determine ANDROID_BUILD_TOP'
- sys.exit(1)
- check_dir_exists(value, '$ANDROID_BUILD_TOP')
- return value
-
-
-def get_android_host_out_or_die():
- value = os.environ.get('ANDROID_HOST_OUT')
- if not value:
- ANDROID_BUILD_TOP = get_android_root_or_die()
- value = get_output_from_command((os.path.join(ANDROID_BUILD_TOP, SOONG_UI_BASH), '--dumpvar-mode', '--abs',
- 'HOST_OUT'))
- if not value:
- print 'Cannot determine ANDROID_HOST_OUT'
- sys.exit(1)
- check_dir_exists(value, '$ANDROID_HOST_OUT')
- return value
-
-
-def get_android_dist_dir_or_die():
- # Check if $DIST_DIR is predefined as environment variable
- value = os.environ.get('DIST_DIR')
- if not value:
- # If not use the default path
- ANDROID_BUILD_TOP = get_android_root_or_die()
- value = os.path.join(os.path.join(ANDROID_BUILD_TOP, 'out'), 'dist')
- if not os.path.isdir(value):
- if os.path.exists(value):
- print '%s is not a directory!' % (value)
- sys.exit(1)
- os.makedirs(value)
- return value
-
-
-def get_native_test_root_or_die():
- android_host_out = get_android_host_out_or_die()
- test_root = os.path.join(android_host_out, 'nativetest64')
- if not os.path.isdir(test_root):
- test_root = os.path.join(android_host_out, 'nativetest')
- if not os.path.isdir(test_root):
- print 'Neither nativetest64 nor nativetest directory exist,' \
- ' please compile first'
- sys.exit(1)
- return test_root
-
-
-def get_test_cmd_or_die(test_root, test_name, enable_xml, test_filter):
- test_path = os.path.join(os.path.join(test_root, test_name), test_name)
- if not os.path.isfile(test_path):
- print 'Cannot find: ' + test_path
- sys.exit(1)
- cmd = [test_path]
- if enable_xml:
- dist_dir = get_android_dist_dir_or_die()
- log_output_path = os.path.join(dist_dir, 'gtest/{0}_test_details.xml'.format(test_name))
- cmd.append('--gtest_output=xml:{0}'.format(log_output_path))
- if test_filter:
- cmd.append('--gtest_filter=%s' % test_filter)
- return cmd
-
-
-# path is relative to Android build top
-def build_target(target, num_tasks):
- ANDROID_BUILD_TOP = get_android_root_or_die()
- build_cmd = [SOONG_UI_BASH, '--make-mode']
- if num_tasks > 1:
- build_cmd.append('-j' + str(num_tasks))
- build_cmd.append(target)
- p = subprocess.Popen(build_cmd, cwd=ANDROID_BUILD_TOP, env=os.environ.copy())
- return_code = p.wait()
- if return_code != 0:
- print 'BUILD FAILED, return code: {0}'.format(str(return_code))
- sys.exit(1)
- return
-
-
-def main():
- """ run_host_unit_tests.py - Run registered host based unit tests
- """
- parser = argparse.ArgumentParser(description='Run host based unit tests.')
- parser.add_argument(
- '--enable_xml',
- type=str2bool,
- dest='enable_xml',
- nargs='?',
- const=True,
- default=False,
- help='Whether to output structured XML log output in out/dist/gtest directory')
- parser.add_argument(
- '-j',
- type=int,
- nargs='?',
- dest='num_tasks',
- const=-1,
- default=-1,
- help='Number of tasks to run at the same time')
- parser.add_argument(
- 'rest', nargs=argparse.REMAINDER, help='-- args, other gtest arguments for each individual test')
- args = parser.parse_args()
-
- build_target('MODULES-IN-system-bt', args.num_tasks)
- TEST_ROOT = get_native_test_root_or_die()
- test_results = []
- for test in HOST_TESTS:
- test_cmd = get_test_cmd_or_die(TEST_ROOT, test, args.enable_xml, args.rest)
- if subprocess.call(test_cmd) != 0:
- test_results.append(False)
- else:
- test_results.append(True)
- if not all(test_results):
- failures = [i for i, x in enumerate(test_results) if not x]
- for index in failures:
- print 'TEST FAILLED: ' + HOST_TESTS[index]
- sys.exit(0)
- print 'TEST PASSED ' + str(len(test_results)) + ' tests were run'
-
- dist_dir = get_android_dist_dir_or_die()
- log_output_path = os.path.join(dist_dir, 'gtest/coverage')
- cmd_path = os.path.join(get_android_root_or_die(), 'packages/modules/Bluetooth/system/test')
- print cmd_path
- cmd = [
- os.path.join(cmd_path, 'gen_coverage.py'),
- '--skip-html',
- '--json-file',
- '-o',
- log_output_path,
- ]
- subprocess.call(cmd)
-
- sys.exit(0)
-
-
-if __name__ == '__main__':
- main()
diff --git a/system/test/run_unit_tests.sh b/system/test/run_unit_tests.sh
deleted file mode 100755
index 41c6016d2d..0000000000
--- a/system/test/run_unit_tests.sh
+++ /dev/null
@@ -1,161 +0,0 @@
-#!/bin/sh
-
-known_tests=(
- audio_bluetooth_hw_test
- bluetooth-test-audio-hal-interface
- bluetooth_test_common
- bluetoothtbd_test
- net_test_audio_a2dp_hw
- net_test_avrcp
- net_test_bluetooth
- net_test_btcore
- net_test_bta
- net_test_bta_security
- net_test_btif
- net_test_btif_profile_queue
- net_test_btif_avrcp_audio_track
- net_test_btif_config_cache
- net_test_device
- net_test_device_iot_config
- net_test_eatt
- net_test_hci
- net_test_stack
- net_test_stack_ad_parser
- net_test_stack_smp
- net_test_types
- net_test_osi
- net_test_performance
- net_test_stack_rfcomm
- net_test_gatt_conn_multiplexing
-)
-
-known_remote_tests=(
- net_test_rfcomm_suite
-)
-
-
-usage() {
- binary="$(basename "$0")"
- echo "Usage: ${binary} --help"
- echo " ${binary} [-i <iterations>] [-s <specific device>] [--all] [<test name>[.<filter>] ...] [--<arg> ...]"
- echo
- echo "Unknown long arguments are passed to the test."
- echo
- echo "Known test names:"
-
- for name in "${known_tests[@]}"
- do
- echo " ${name}"
- done
-
- echo
- echo "Known tests that need a remote device:"
- for name in "${known_remote_tests[@]}"
- do
- echo " ${name}"
- done
-}
-
-iterations=1
-device=
-tests=()
-test_args=()
-while [ $# -gt 0 ]
-do
- case "$1" in
- -h|--help)
- usage
- exit 0
- ;;
- -i)
- shift
- if [ $# -eq 0 ]; then
- echo "error: number of iterations expected" 1>&2
- usage
- exit 2
- fi
- iterations=$(( $1 ))
- shift
- ;;
- -s)
- shift
- if [ $# -eq 0 ]; then
- echo "error: no device specified" 1>&2
- usage
- exit 2
- fi
- device="$1"
- shift
- ;;
- --all)
- tests+=( "${known_tests[@]}" )
- shift
- ;;
- --*)
- test_args+=( "$1" )
- shift
- ;;
- *)
- tests+=( "$1" )
- shift
- ;;
- esac
-done
-
-if [ "${#tests[@]}" -eq 0 ]; then
- tests+=( "${known_tests[@]}" )
-fi
-
-adb=( "adb" )
-if [ -n "${device}" ]; then
- adb+=( "-s" "${device}" )
-fi
-
-source ${ANDROID_BUILD_TOP}/build/envsetup.sh
-target_arch=$(gettargetarch)
-
-failed_tests=()
-for spec in "${tests[@]}"
-do
- name="${spec%%.*}"
- if [[ $target_arch == *"64"* ]]; then
- binary="/data/nativetest64/${name}/${name}"
- if [ -e "${ANDROID_PRODUCT_OUT}${binary}64" ]; then
- binary="/data/nativetest64/${name}/${name}64"
- fi
- else
- binary="/data/nativetest/${name}/${name}"
- fi
-
- push_command=( "${adb[@]}" push {"${ANDROID_PRODUCT_OUT}",}"${binary}" )
- test_command=( "${adb[@]}" shell "${binary}" )
- if [ "${name}" != "${spec}" ]; then
- filter="${spec#*.}"
- test_command+=( "--gtest_filter=${filter}" )
- fi
- test_command+=( "${test_args[@]}" )
-
- echo "--- ${name} ---"
- echo "pushing..."
- "${push_command[@]}"
- echo "running..."
- failed_count=0
- for i in $(seq 1 ${iterations})
- do
- "${test_command[@]}" || failed_count=$(( $failed_count + 1 ))
- done
-
- if [ $failed_count != 0 ]; then
- failed_tests+=( "${name} ${failed_count}/${iterations}" )
- fi
-done
-
-if [ "${#failed_tests[@]}" -ne 0 ]; then
- for failed_test in "${failed_tests[@]}"
- do
- echo "!!! FAILED TEST: ${failed_test} !!!"
- done
- exit 1
-fi
-
-exit 0
diff --git a/system/test/suite/Android.bp b/system/test/suite/Android.bp
index 29fe4ecc35..57988a356b 100644
--- a/system/test/suite/Android.bp
+++ b/system/test/suite/Android.bp
@@ -117,13 +117,14 @@ cc_test {
"gatt/gatt_unittest.cc",
],
static_libs: [
- "android.hardware.audio.common-V1-ndk",
+ "android.hardware.audio.common-V2-ndk",
"android.hardware.bluetooth.audio-V3-ndk",
"android.hardware.bluetooth@1.0",
"android.hardware.bluetooth@1.1",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
"android.media.audio.common.types-V2-ndk",
+ "libbluetooth_gd",
"libchrome",
"libevent",
],
diff --git a/system/tools/Android.mk.disabled b/system/tools/Android.mk.disabled
deleted file mode 100644
index 5053e7d643..0000000000
--- a/system/tools/Android.mk.disabled
+++ /dev/null
@@ -1 +0,0 @@
-include $(call all-subdir-makefiles)
diff --git a/system/tools/bdtool/Android.mk.disabled b/system/tools/bdtool/Android.mk.disabled
deleted file mode 100644
index 76b8dceb1a..0000000000
--- a/system/tools/bdtool/Android.mk.disabled
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# Copyright 2014 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-# Bluetooth tools for target
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := net_bdtool
-
-LOCAL_SRC_FILES := \
- adapter.c \
- bdtool.c \
- ../../test/suite/support/callbacks.c \
- ../../test/suite/support/gatt.c \
- ../../test/suite/support/hal.c \
- ../../test/suite/support/pan.c
-
-LOCAL_STATIC_LIBRARIES := \
- libbtcore \
- libosi
-
-LOCAL_C_INCLUDES := \
- $(LOCAL_PATH)/../../test/suite \
- $(LOCAL_PATH)/../..
-
-LOCAL_SHARED_LIBRARIES := \
- libhardware liblog
-
-LOCAL_CFLAGS += $(bluetooth_CFLAGS)
-LOCAL_CONLYFLAGS += $(bluetooth_CONLYFLAGS)
-LOCAL_CPPFLAGS += $(bluetooth_CPPFLAGS)
-
-include $(BUILD_EXECUTABLE)
diff --git a/system/tools/bdtool/adapter.c b/system/tools/bdtool/adapter.c
deleted file mode 100644
index 3b964a0f78..0000000000
--- a/system/tools/bdtool/adapter.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2014 Google, Inc.
- *
- * 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 "support/adapter.h"
-
-#include "base.h"
-#include "btcore/include/property.h"
-#include "support/callbacks.h"
-#include "types/bluetooth/uuid.h"
-#include "types/raw_address.h"
-
-static bt_state_t state;
-static int property_count = 0;
-static bt_property_t* properties = NULL;
-static bt_discovery_state_t discovery_state;
-static bt_acl_state_t acl_state;
-static bt_bond_state_t bond_state;
-
-static void parse_properties(int num_properties, bt_property_t* property);
-
-// Returns the current adapter state.
-bt_state_t adapter_get_state() { return state; }
-
-// Returns the number of adapter properties.
-int adapter_get_property_count() { return property_count; }
-
-// Returns the specified property.
-bt_property_t* adapter_get_property(bt_property_type_t type) {
- for (int i = 0; i < property_count; ++i) {
- if (properties[i].type == type) {
- return &properties[i];
- }
- }
-
- return NULL;
-}
-
-// Returns the device discovery state.
-bt_discovery_state_t adapter_get_discovery_state() { return discovery_state; }
-
-// Returns the device acl state.
-bt_acl_state_t adapter_get_acl_state() { return acl_state; }
-
-// Returns the device bond state.
-bt_bond_state_t adapter_get_bond_state() { return bond_state; }
-
-// callback
-void acl_state_changed(bt_status_t status, RawAddress* remote_bd_addr,
- bt_acl_state_t state) {
- acl_state = state;
- CALLBACK_RET();
-}
-
-// callback
-void adapter_properties(bt_status_t status, int num_properties,
- bt_property_t* new_properties) {
- property_free_array(properties, property_count);
- properties = property_copy_array(new_properties, num_properties);
- property_count = num_properties;
-
- CALLBACK_RET();
-}
-
-// callback
-void adapter_state_changed(bt_state_t new_state) {
- state = new_state;
- CALLBACK_RET();
-}
-
-// callback
-void bond_state_changed(bt_status_t status, RawAddress* bdaddr,
- bt_bond_state_t state) {
- char buf[18];
- bond_state = state;
-
- const char* state_name = "Bond state unknown";
- switch (bond_state) {
- case BT_BOND_STATE_NONE:
- state_name = "Bond state none";
- break;
-
- case BT_BOND_STATE_BONDING:
- state_name = "Bond state bonding";
- break;
-
- case BT_BOND_STATE_BONDED:
- state_name = "Bond state bonded";
- break;
-
- // default none
- }
- fprintf(stdout, "Bond state changed callback addr:%s state:%s\n",
- bdaddr_to_string(bdaddr, buf, sizeof(buf)), state_name);
-
- CALLBACK_RET();
-}
-
-// callback
-void device_found(int num_properties, bt_property_t* property) {
- fprintf(stdout, "Device found num_properties:%d\n", num_properties);
- parse_properties(num_properties, property);
-
- CALLBACK_RET();
-}
-
-// callback
-void discovery_state_changed(bt_discovery_state_t state) {
- const char* state_name = "Unknown";
- discovery_state = state;
-
- switch (discovery_state) {
- case BT_DISCOVERY_STOPPED:
- state_name = "Discovery stopped";
- break;
-
- case BT_DISCOVERY_STARTED:
- state_name = "Discovery started";
- break;
-
- // default omitted
- }
- fprintf(stdout, "Discover state %s\n", state_name);
-
- CALLBACK_RET();
-}
-
-// callback
-void remote_device_properties(bt_status_t status, RawAddress* bdaddr,
- int num_properties, bt_property_t* properties) {
- char buf[18];
- fprintf(stdout, "Device found bdaddr:%s num_properties:%d\n",
- bdaddr_to_string(bdaddr, buf, sizeof(buf)), num_properties);
-
- parse_properties(num_properties, properties);
-
- CALLBACK_RET();
-}
-
-// callback
-void ssp_request(RawAddress* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod,
- bt_ssp_variant_t pairing_variant, uint32_t pass_key) {
- char* pairing_variant_name = "Unknown";
-
- switch (pairing_variant) {
- case BT_SSP_VARIANT_PASSKEY_CONFIRMATION:
- pairing_variant_name = "Passkey confirmation";
- break;
- case BT_SSP_VARIANT_PASSKEY_ENTRY:
- pairing_variant_name = "Passkey entry";
- break;
-
- case BT_SSP_VARIANT_CONSENT:
- pairing_variant_name = "Passkey consent";
- break;
-
- case BT_SSP_VARIANT_PASSKEY_NOTIFICATION:
- pairing_variant_name = "Passkey notification";
- break;
- }
-
- fprintf(stdout,
- "Got ssp request device_class:%u passkey:%x pairing_variant:%s\n",
- cod, pass_key, pairing_variant_name);
- char buf[18];
- fprintf(stdout, "Device found:%s %s\n",
- bdaddr_to_string(remote_bd_addr, buf, sizeof(buf)), bd_name->name);
-
- fprintf(stdout, "auto-accepting bond\n");
- bool accept = true;
- int rc = bt_interface->ssp_reply(remote_bd_addr, pairing_variant,
- (uint8_t)accept, pass_key);
- CALLBACK_RET();
-}
-
-// callback
-void thread_evt(bt_cb_thread_evt evt) { CALLBACK_RET(); }
-
-static void parse_properties(int num_properties, bt_property_t* property) {
- while (num_properties-- > 0) {
- switch (property->type) {
- case BT_PROPERTY_BDNAME: {
- const bt_bdname_t* name = property_as_name(property);
- if (name) fprintf(stdout, " name:%s\n", name->name);
- } break;
-
- case BT_PROPERTY_BDADDR: {
- char buf[18];
- const RawAddress* addr = property_as_addr(property);
- if (addr)
- fprintf(stdout, " addr:%s\n",
- bdaddr_to_string(addr, buf, sizeof(buf)));
- } break;
-
- case BT_PROPERTY_UUIDS: {
- size_t num_uuid;
- const Uuid* uuid = property_as_uuids(property, &num_uuid);
- if (uuid) {
- for (size_t i = 0; i < num_uuid; i++) {
- fprintf(stdout, " uuid:%zd: ", i);
- for (size_t j = 0; j < sizeof(uuid); j++) {
- fprintf(stdout, "%02x", uuid->uu[j]);
- }
- fprintf(stdout, "\n");
- }
- }
- } break;
-
- case BT_PROPERTY_TYPE_OF_DEVICE: {
- bt_device_type_t device_type = property_as_device_type(property);
- if (device_type) {
- const struct {
- const char* device_type;
- } device_type_lookup[] = {
- {"Unknown"},
- {"Classic Only"},
- {"BLE Only"},
- {"Both Classic and BLE"},
- };
- int idx = (int)device_type;
- if (idx > BT_DEVICE_DEVTYPE_DUAL) idx = 0;
- fprintf(stdout, " device_type:%s\n",
- device_type_lookup[idx].device_type);
- }
- } break;
-
- case BT_PROPERTY_CLASS_OF_DEVICE: {
- const bt_device_class_t* dc = property_as_device_class(property);
- int dc_int = device_class_to_int(dc);
- fprintf(stdout, " device_class:0x%x\n", dc_int);
- } break;
-
- case BT_PROPERTY_REMOTE_RSSI: {
- int8_t rssi = property_as_rssi(property);
- fprintf(stdout, " rssi:%d\n", rssi);
- } break;
-
- case BT_PROPERTY_REMOTE_FRIENDLY_NAME: {
- const bt_bdname_t* name = property_as_name(property);
- if (name) fprintf(stdout, " remote_name:%s\n", name->name);
- } break;
-
- case BT_PROPERTY_SERVICE_RECORD:
- case BT_PROPERTY_ADAPTER_SCAN_MODE:
- case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
- case BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT:
- case BT_PROPERTY_REMOTE_VERSION_INFO:
- case BT_PROPERTY_LOCAL_LE_FEATURES:
- case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
- default: {
- fprintf(stderr, "Unhandled property type:%d len:%d\n", property->type,
- property->len);
- uint8_t* p = (uint8_t*)property->val;
- for (int i = 0; i < property->len; ++i, p++) {
- fprintf(stderr, " %02x", *p);
- }
- if (property->len != 0) fprintf(stderr, "\n");
- }
- }
- property++;
- }
-}
diff --git a/system/tools/bdtool/bdtool.c b/system/tools/bdtool/bdtool.c
deleted file mode 100644
index 07970a7744..0000000000
--- a/system/tools/bdtool/bdtool.c
+++ /dev/null
@@ -1,362 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2014 Google, Inc.
- *
- * 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 <getopt.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "btcore/include/property.h"
-#include "osi/include/osi.h"
-#include "test/suite/support/callbacks.h"
-#include "test/suite/support/hal.h"
-#include "types/bluetooth/uuid.h"
-#include "types/raw_address.h"
-
-static const Uuid HFP_UUID =
- Uuid::From128BitBE({{0x00, 0x00, 0x11, 0x1E, 0x00, 0x00, 0x10, 0x00, 0x80,
- 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}});
-static const Uuid HFP_AG_UUID =
- Uuid::From128BitBE({{0x00, 0x00, 0x11, 0x1F, 0x00, 0x00, 0x10, 0x00, 0x80,
- 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB}});
-
-const bt_interface_t* bt_interface;
-
-RawAddress bt_remote_bdaddr;
-
-static int f_verbose;
-static bool discover = false;
-static bool discoverable = false;
-static bool bond = false;
-static bool up = false;
-static bool get_name = false;
-static bool set_name = false;
-static bool sco_listen = false;
-static bool sco_connect = false;
-
-static int timeout_in_sec = 30;
-static char* bd_name;
-
-static struct option long_options[] = {
- {"bdaddr", required_argument, 0, 0}, {"discover", no_argument, 0, 0},
- {"discoverable", no_argument, 0, 0}, {"time", required_argument, 0, 0},
- {"bond", no_argument, 0, 0}, {"up", no_argument, 0, 0},
- {"verbose", no_argument, 0, 0}, {"get_name", no_argument, 0, 0},
- {"set_name", required_argument, 0, 0}, {"sco_listen", no_argument, 0, 0},
- {"sco_connect", no_argument, 0, 0}, {0, 0, 0, 0}};
-
-static void usage(const char* name);
-static bool parse_args(int argc, char** argv);
-static void sig_handler(int signo);
-
-bt_property_t* adapter_get_property(bt_property_type_t type);
-
-int main(int argc, char** argv) {
- if (!parse_args(argc, argv)) {
- usage(argv[0]);
- }
-
- if (bond && discoverable) {
- fprintf(stderr, "Can only select either bond or discoverable, not both\n");
- usage(argv[0]);
- }
-
- if (sco_listen && sco_connect) {
- fprintf(stderr,
- "Can only select either sco_listen or sco_connect, not both\n");
- usage(argv[0]);
- }
-
- if (!bond && !discover && !discoverable && !up && !get_name && !set_name &&
- !sco_listen && !sco_connect) {
- fprintf(stderr, "Must specify one command\n");
- usage(argv[0]);
- }
-
- if (signal(SIGINT, sig_handler) == SIG_ERR) {
- fprintf(stderr, "Will be unable to catch signals\n");
- }
-
- fprintf(stdout, "Bringing up bluetooth adapter\n");
- if (!hal_open(callbacks_get_adapter_struct())) {
- fprintf(stderr, "Unable to open Bluetooth HAL.\n");
- return 1;
- }
-
- if (discover) {
- CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
- fprintf(stdout, "BT adapter is up\n");
-
- fprintf(stdout, "Starting to start discovery\n");
- CALL_AND_WAIT(bt_interface->start_discovery(), discovery_state_changed);
- fprintf(stdout, "Started discovery for %d seconds\n", timeout_in_sec);
-
- sleep(timeout_in_sec);
-
- fprintf(stdout, "Starting to cancel discovery\n");
- CALL_AND_WAIT(bt_interface->cancel_discovery(), discovery_state_changed);
- fprintf(stdout, "Cancelled discovery after %d seconds\n", timeout_in_sec);
- }
-
- if (discoverable) {
- CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
- fprintf(stdout, "BT adapter is up\n");
-
- bt_property_t* property =
- property_new_scan_mode(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
-
- int rc = bt_interface->set_adapter_property(property);
- fprintf(stdout, "Set rc:%d device as discoverable for %d seconds\n", rc,
- timeout_in_sec);
-
- sleep(timeout_in_sec);
-
- property_free(property);
- }
-
- if (bond) {
- if (bdaddr_is_empty(&bt_remote_bdaddr)) {
- fprintf(stderr,
- "Must specify a remote device address [ "
- "--bdaddr=xx:yy:zz:aa:bb:cc ]\n");
- exit(1);
- }
-
- CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
- fprintf(stdout, "BT adapter is up\n");
-
- int rc = bt_interface->create_bond(
- &bt_remote_bdaddr, 0 /* UNKNOWN; Currently not documented :( */);
- fprintf(stdout, "Started bonding:%d for %d seconds\n", rc, timeout_in_sec);
-
- sleep(timeout_in_sec);
- }
-
- if (up) {
- CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
- fprintf(stdout, "BT adapter is up\n");
-
- fprintf(stdout, "Waiting for %d seconds\n", timeout_in_sec);
- sleep(timeout_in_sec);
- }
-
- if (get_name) {
- CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
- fprintf(stdout, "BT adapter is up\n");
- int error;
- CALL_AND_WAIT(
- error = bt_interface->get_adapter_property(BT_PROPERTY_BDNAME),
- adapter_properties);
- if (error != BT_STATUS_SUCCESS) {
- fprintf(stderr, "Unable to get adapter property\n");
- exit(1);
- }
- bt_property_t* property = adapter_get_property(BT_PROPERTY_BDNAME);
- const bt_bdname_t* name = property_as_name(property);
- if (name)
- printf("Queried bluetooth device name:%s\n", name->name);
- else
- printf("No name\n");
- }
-
- if (set_name) {
- CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
- fprintf(stdout, "BT adapter is up\n");
-
- bt_property_t* property = property_new_name(bd_name);
- printf("Setting bluetooth device name to:%s\n", bd_name);
- int error;
- CALL_AND_WAIT(error = bt_interface->set_adapter_property(property),
- adapter_properties);
- if (error != BT_STATUS_SUCCESS) {
- fprintf(stderr, "Unable to set adapter property\n");
- exit(1);
- }
- CALL_AND_WAIT(
- error = bt_interface->get_adapter_property(BT_PROPERTY_BDNAME),
- adapter_properties);
- if (error != BT_STATUS_SUCCESS) {
- fprintf(stderr, "Unable to get adapter property\n");
- exit(1);
- }
- property_free(property);
- sleep(timeout_in_sec);
- }
-
- const int app_uid = 0;
-
- if (sco_listen) {
- CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
- fprintf(stdout, "BT adapter is up\n");
-
- bt_property_t* property =
- property_new_scan_mode(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
- CALL_AND_WAIT(bt_interface->set_adapter_property(property),
- adapter_properties);
- property_free(property);
-
- const btsock_interface_t* sock =
- bt_interface->get_profile_interface(BT_PROFILE_SOCKETS_ID);
-
- int rfcomm_fd = INVALID_FD;
- int error =
- sock->listen(BTSOCK_RFCOMM, "meow", (const uint8_t*)&HFP_AG_UUID, 0,
- &rfcomm_fd, 0, app_uid);
- if (error != BT_STATUS_SUCCESS) {
- fprintf(stderr, "Unable to listen for incoming RFCOMM socket: %d\n",
- error);
- exit(1);
- }
-
- int sock_fd = INVALID_FD;
- error = sock->listen(BTSOCK_SCO, NULL, NULL, 5, &sock_fd, 0, app_uid);
- if (error != BT_STATUS_SUCCESS) {
- fprintf(stderr, "Unable to listen for incoming SCO sockets: %d\n", error);
- exit(1);
- }
- fprintf(stdout, "Waiting for incoming SCO connections...\n");
- sleep(timeout_in_sec);
- }
-
- if (sco_connect) {
- if (bdaddr_is_empty(&bt_remote_bdaddr)) {
- fprintf(stderr,
- "Must specify a remote device address [ "
- "--bdaddr=xx:yy:zz:aa:bb:cc ]\n");
- exit(1);
- }
-
- CALL_AND_WAIT(bt_interface->enable(), adapter_state_changed);
- fprintf(stdout, "BT adapter is up\n");
-
- const btsock_interface_t* sock =
- bt_interface->get_profile_interface(BT_PROFILE_SOCKETS_ID);
-
- int rfcomm_fd = INVALID_FD;
- int error =
- sock->connect(&bt_remote_bdaddr, BTSOCK_RFCOMM,
- (const uint8_t*)&HFP_AG_UUID, 0, &rfcomm_fd, 0, app_uid);
- if (error != BT_STATUS_SUCCESS) {
- fprintf(stderr, "Unable to connect to RFCOMM socket: %d.\n", error);
- exit(1);
- }
-
- WAIT(acl_state_changed);
-
- fprintf(stdout, "Establishing SCO connection...\n");
-
- int sock_fd = INVALID_FD;
- error = sock->connect(&bt_remote_bdaddr, BTSOCK_SCO, NULL, 5, &sock_fd, 0,
- app_uid);
- if (error != BT_STATUS_SUCCESS) {
- fprintf(stderr, "Unable to connect to SCO socket: %d.\n", error);
- exit(1);
- }
- sleep(timeout_in_sec);
- }
-
- CALL_AND_WAIT(bt_interface->disable(), adapter_state_changed);
- fprintf(stdout, "BT adapter is down\n");
-}
-
-static void sig_handler(int signo) {
- if (signo == SIGINT) {
- fprintf(stderr, "Received SIGINT\n");
- CALL_AND_WAIT(bt_interface->disable(), adapter_state_changed);
- fprintf(stderr, "BT adapter is down\n");
- exit(1);
- }
-}
-
-static void usage(const char* name) {
- fprintf(stderr,
- "Usage: %s "
- "[--bond|--discover|--discoverable|--up|--sco_listen|--sco_connect] "
- "[--bdaddr=<bdaddr>] [--time=<time_in_sec>] --verbose\n",
- name);
- fprintf(stderr, " bond: Discover actively advertising devices\n");
- fprintf(stderr, " discover: Discover actively advertising devices\n");
- fprintf(stderr,
- " discoverable: Set into a connectable and discoverable mode\n");
- fprintf(stderr, " up: Only bring up stack\n");
- fprintf(stderr, " sco_listen: Listen for incoming SCO connections\n");
- fprintf(stderr,
- " sco_connect: Establish a SCO connection with another device\n");
- fprintf(stderr, " time: Time to hold in the specified mode\n");
- exit(1);
-}
-
-static bool parse_args(int argc, char** argv) {
- while (1) {
- int option_index = 0;
- int c = getopt_long_only(argc, argv, "", long_options, &option_index);
- if (c != 0) break;
-
- switch (c) {
- case 0:
- if (option_index == 0) {
- if (!string_to_bdaddr(optarg, &bt_remote_bdaddr)) {
- return false;
- }
- }
- if (option_index == 1) {
- discover = true;
- }
- if (option_index == 2) {
- discoverable = true;
- }
- if (option_index == 3) {
- timeout_in_sec = atoi(optarg);
- }
- if (option_index == 4) {
- bond = true;
- }
- if (option_index == 5) {
- up = true;
- }
- if (option_index == 6) {
- f_verbose++;
- }
- if (option_index == 7) {
- get_name = true;
- }
- if (option_index == 8) {
- bd_name = (char*)optarg;
- set_name = true;
- }
- if (option_index == 9) {
- sco_listen = true;
- }
- if (option_index == 10) {
- sco_connect = true;
- }
- break;
-
- default:
- fprintf(stderr, "?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc) {
- fprintf(stderr, "non-option ARGV-elements: ");
- while (optind < argc) fprintf(stderr, "%s ", argv[optind++]);
- fprintf(stderr, "\n");
- return false;
- }
- return true;
-}
diff --git a/system/tools/hci/Android.mk.disabled b/system/tools/hci/Android.mk.disabled
deleted file mode 100644
index 9244f45a9d..0000000000
--- a/system/tools/hci/Android.mk.disabled
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright 2014 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-# Bluetooth HCI tools for target
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := net_hci
-
-LOCAL_SRC_FILES := main.c
-LOCAL_STATIC_LIBRARIES := libosi
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../
-
-LOCAL_CFLAGS += $(bluetooth_CFLAGS)
-LOCAL_CONLYFLAGS += $(bluetooth_CONLYFLAGS)
-LOCAL_CPPFLAGS += $(bluetooth_CPPFLAGS)
-
-include $(BUILD_EXECUTABLE)
diff --git a/system/tools/hci/main.c b/system/tools/hci/main.c
deleted file mode 100644
index 093af6bb3a..0000000000
--- a/system/tools/hci/main.c
+++ /dev/null
@@ -1,216 +0,0 @@
-#include <hardware/bluetooth.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "osi/include/osi.h"
-
-typedef int (*handler_t)(int argc, char** argv);
-
-typedef enum {
- HCI_PACKET_COMMAND = 1,
- HCI_PACKET_ACL_DATA = 2,
- HCI_PACKET_SCO_DATA = 3,
- HCI_PACKET_EVENT = 4,
- HCI_PACKET_ISO = 5,
-} hci_packet_t;
-
-typedef struct {
- const char* name;
- const char* help;
- handler_t handler;
-} command_t;
-
-static int help(int argc, char** argv);
-static int set_discoverable(int argc, char** argv);
-static int set_name(int argc, char** argv);
-static int set_pcm_loopback(int argc, char** argv);
-static int set_sco_route(int argc, char** argv);
-
-static bool write_hci_command(hci_packet_t type, const void* packet,
- size_t length);
-static const command_t* find_command(const char* name);
-static void usage(const char* name);
-
-static const command_t commands[] = {
- {"help", "<command> - shows help text for <command>.", help},
- {"setDiscoverable",
- "(true|false) - whether the controller should be discoverable.",
- set_discoverable},
- {"setName", "<name> - sets the device's Bluetooth name to <name>.",
- set_name},
- {"setPcmLoopback",
- "(true|false) - enables or disables PCM loopback on the controller.",
- set_pcm_loopback},
- {"setScoRoute",
- "(pcm|i2s|uart) - sets the SCO packet route to one of the specified "
- "buses.",
- set_sco_route},
-};
-
-static int help(int argc, char** argv) {
- if (!argc) {
- printf("No help command specified.\n");
- return 1;
- }
-
- const command_t* command = find_command(argv[0]);
- if (!command) {
- printf("No command named '%s'.\n", argv[0]);
- return 2;
- }
-
- printf("%s %s\n", argv[0], command->help);
- return 0;
-}
-
-static int set_discoverable(int argc, char** argv) {
- if (argc != 1) {
- printf("Discoverable mode not specified.\n");
- return 1;
- }
-
- if (strcmp(argv[0], "true") && strcmp(argv[0], "false")) {
- printf("Invalid discoverable mode '%s'.\n", argv[0]);
- return 2;
- }
-
- uint8_t packet[] = {0x1A, 0x0C, 0x01, 0x00};
- if (argv[0][0] == 't') packet[ARRAY_SIZE(packet) - 1] = 0x03;
-
- return !write_hci_command(HCI_PACKET_COMMAND, packet, ARRAY_SIZE(packet));
-}
-
-static int set_name(int argc, char** argv) {
- if (argc != 1) {
- printf("Device name not specified.\n");
- return 1;
- }
-
- size_t len = strlen(argv[0]);
- if (len > 247) {
- printf("Device name cannot exceed 247 bytes.\n");
- return 2;
- }
-
- uint8_t packet[251] = {0x13, 0x0C, 248};
- memcpy(&packet[3], argv[0], len + 1);
-
- if (!write_hci_command(HCI_PACKET_COMMAND, packet, sizeof(packet))) return 1;
-
- memset(&packet[0], 0, sizeof(packet));
- packet[0] = 0x52;
- packet[1] = 0x0C;
- packet[2] = 0xF1; // HCI command packet length.
- packet[3] = 0x01; // FEC required.
- packet[4] = len + 1;
- packet[5] = 0x09; // Device name field tag.
- memcpy(&packet[6], argv[0], len);
- return !write_hci_command(HCI_PACKET_COMMAND, packet, 0xF4);
-}
-
-static int set_pcm_loopback(int argc, char** argv) {
- if (argc != 1) {
- printf("PCM loopback mode not specified.\n");
- return 1;
- }
-
- if (strcmp(argv[0], "true") && strcmp(argv[0], "false")) {
- printf("Invalid PCM mode '%s'.\n", argv[0]);
- return 2;
- }
-
- uint8_t packet[] = {0x24, 0xFC, 0x01, 0x00};
- if (argv[0][0] == 't') packet[ARRAY_SIZE(packet) - 1] = 0x01;
-
- return !write_hci_command(HCI_PACKET_COMMAND, packet, ARRAY_SIZE(packet));
-}
-
-static int set_sco_route(int argc, char** argv) {
- if (argc != 1) {
- printf("SCO route parameter must be specified.\n");
- return 1;
- }
-
- uint8_t route = 0xFF;
- if (!strcmp(argv[0], "pcm"))
- route = 0;
- else if (!strcmp(argv[0], "i2s"))
- route = 3;
- else if (!strcmp(argv[0], "uart"))
- route = 1;
-
- if (route == 0xFF) {
- printf("Invalid SCO route specified: %s\n", argv[0]);
- return 2;
- }
-
- uint8_t packet[] = {0x1C, 0xFC, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00};
- packet[3] = route;
-
- return !write_hci_command(HCI_PACKET_COMMAND, packet, ARRAY_SIZE(packet));
-}
-
-int main(int argc, char** argv) {
- if (argc < 2) {
- usage(argv[0]);
- return -1;
- }
-
- const command_t* command = find_command(argv[1]);
- if (!command) {
- printf("Unrecognized command '%s'.\n", argv[1]);
- return -2;
- }
-
- if (!command->handler) {
- printf("Unhandled command '%s'.\n", argv[1]);
- return -3;
- }
-
- return command->handler(argc - 2, &argv[2]);
-}
-
-static bool write_hci_command(hci_packet_t type, const void* packet,
- size_t length) {
- int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (sock == INVALID_FD) goto error;
-
- struct sockaddr_in addr;
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(0x7F000001);
- addr.sin_port = htons(8873);
- int ret;
- OSI_NO_INTR(ret = connect(sock, (const struct sockaddr*)&addr, sizeof(addr)));
- if (ret == -1) goto error;
-
- if (send(sock, &type, 1, 0) != 1) goto error;
-
- if (send(sock, &length, 2, 0) != 2) goto error;
-
- if (send(sock, packet, length, 0) != (ssize_t)length) goto error;
-
- close(sock);
- return true;
-
-error:;
- close(sock);
- return false;
-}
-
-static const command_t* find_command(const char* name) {
- for (size_t i = 0; i < ARRAY_SIZE(commands); ++i)
- if (!strcmp(commands[i].name, name)) return &commands[i];
- return NULL;
-}
-
-static void usage(const char* name) {
- printf("Usage: %s <command> [options]\n", name);
- printf("Commands:\n");
- for (size_t i = 0; i < ARRAY_SIZE(commands); ++i)
- printf(" %s\n", commands[i].name);
- printf("For detailed help on a command, run '%s help <command>'.\n", name);
-}
diff --git a/system/tools/scripts/change_types.sh b/system/tools/scripts/change_types.sh
deleted file mode 100755
index 4467b89677..0000000000
--- a/system/tools/scripts/change_types.sh
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/bash
-
-# This script will recursively search all |FILES| from the current
-# directory and replace all |TYPES| according to the list below.
-
-# NOTE 1:
-# If this script is run from .../packages/modules/Bluetooth/system (as it's intended to be),
-# please edit stack/include/bt_types.h next and remove the typedef's
-# near the top and restore the definitions of TRUE and FALSE. These
-# are still used in the vnd_* files and device specific repositories.
-
-# NOTE 2:
-# The list of files to be modified also includes "*.patch", which means
-# this script can be used to help cherry-picking changes from older
-# branches. Follow this workflow outline:
-# 1. git format-patch [-1] <your sha1>
-# 2. Run change_type script on patch[es]
-# 3. git apply / git am
-
-
-# Regular expression matching the file name
-FILES="\.h$|\.c$|\.cpp$|\.cc$|\.patch$"
-
-# Search/replace terms, separated by ":"
-TYPES=(
- "UINT8 :uint8_t "
- "UINT16 :uint16_t "
- "UINT32 :uint32_t "
- "UINT64 :uint64_t "
- "INT8 :int8_t "
- "INT16 :int16_t "
- "INT32 :int32_t "
- "INT64 :int64_t "
- "UINT8:uint8_t"
- "UINT16:uint16_t"
- "UINT32:uint32_t"
- "UINT64:uint64_t"
- "INT8:int8_t"
- "INT16:int16_t"
- "INT32:int32_t"
- "INT64:int64_t"
- "BOOLEAN:bool "
- "TRUE:true"
- "FALSE:false"
- "__FUNCTION__:__func__"
-)
-
-function process_file
-{
- echo -n "Processing file $1 "
-
- for tt in "${TYPES[@]}" ;
- do
- before=${tt%%:*}
- after=${tt#*:}
-
- echo -n "."
- sed -i -e "s/\b${before}/${after}/g; s/${after}_/${before}_/g;" "$1"
- done
- echo
-}
-
-function process_files
-{
- until [ -z "$1" ]
- do
- process_file "$1"
- shift
- done
-}
-
-
-# Let's do this ...
-process_files `find ./ | grep -E "${FILES}"`
-
-# All done ...
-echo
-echo "All done."
-
-# Try to be helpful ...
-PWD=`pwd`
-if [[ "${PWD}" == */packages/modules/Bluetooth/system ]]
-then
- echo "Please edit ${PWD}/stack/include/bt_types.h next."
-fi
diff --git a/system/vendor_libs/linux/interface/Android.bp b/system/vendor_libs/linux/interface/Android.bp
index 26e11fbcb8..a47a57dbd8 100644
--- a/system/vendor_libs/linux/interface/Android.bp
+++ b/system/vendor_libs/linux/interface/Android.bp
@@ -46,7 +46,6 @@ cc_binary {
static_libs: [
"async_fd_watcher",
],
- c_std: "c99",
init_rc: ["android.hardware.bluetooth@1.1-service.btlinux.rc"],
}
diff --git a/tools/OWNERS b/tools/OWNERS
index e950f0b0db..ec93a16eba 100644
--- a/tools/OWNERS
+++ b/tools/OWNERS
@@ -3,6 +3,7 @@
cmanton@google.com
cncn@google.com
jpawlowski@google.com
+licorne@google.com
mylesgw@google.com
optedoblivion@google.com
qasimj@google.com
diff --git a/tools/bt-api-plumber/bt-api-plumber-9000.sh b/tools/bt-api-plumber/bt-api-plumber-9000.sh
deleted file mode 100755
index e4e4e62e13..0000000000
--- a/tools/bt-api-plumber/bt-api-plumber-9000.sh
+++ /dev/null
@@ -1,559 +0,0 @@
-#!/bin/bash
-
-YELLOW="\033[1;33m"
-NOCOLOR="\033[0m"
-BLUE="\033[1;34m"
-RED="\033[1;91m"
-
-# TODO(optedoblivion): Check for 'git' and 'clang' binary
-
-function check_environment {
- if [[ -z "${ANDROID_BUILD_TOP}" ]] || [[ -z "${ANDROID_HOST_OUT}" ]] ; then
- echo -e "${RED}ANDROID_BUILD_TOP${NOCOLOR} or ${RED}ANDROID_HOST_OUT${NOCOLOR} is not set for host run"
- echo -e "Navigate to android root and run:"
- echo -e "${YELLOW}"
- echo -e ". build/envsetup.sh"
- echo -e "lunch <fish>"
- echo -e "${NOCOLOR}"
- echo
- exit 1
- fi
-}
-
-QUOTES=(
- "It's a-me, Martino!"
- "Hello!"
- "Wahoo!"
- "Oh yeah!"
- "Martino time!"
- "Lucky!"
- "Hui hew! Just what I needed!"
- "Spin! Hammer! Fire! Jump!"
- "Yiiiiiipeee!"
- "Yeah, ha ha ha!"
- "Waha!"
- "Let's-a go!"
- "Here we go!"
- "Yes! I'm the winner!"
- "Luigi!"
- "Way to go!"
- "Here I go!"
- "Mama Mia!"
-)
-
-VERBOSE=false
-
-# Controller
-CONTROLLER=false
-CONTROLLER_FILES=(
- "system/gd/hci/controller.h"
- "system/gd/hci/controller.cc"
- "system/gd/hci/controller.cc"
- "system/gd/hci/controller_mock.h"
- "system/gd/hci/controller_test.cc"
-)
-CONTROLLER_FIND_PATTERNS=(
- " LeRand(LeRandCallback cb);"
- "Controller::impl::le_rand_cb<LeRandCompleteView>, cb));"
- "impl::le_rand, cb);"
- " (LeRandCallback cb));"
- " le_rand_set.get_future().wait();"
-)
-CONTROLLER_CODE_TEMPLATES=(
- " virtual void :CamelApiName:();"
- " }\\\n\\\n void :snake_api_name:() {\\\n \\\\\/\\\\\/TODO(WHOAMI): Implement HCI Call"
- "}\\\n\\\nvoid Controller:::CamelApiName:() {\\\n CallOn(impl_.get(), \\\\\&impl:::snake_api_name:);"
- " MOCK_METHOD(void, :CamelApiName:, ());"
- "}\\\n\\\nTEST_F(ControllerTest, :CamelApiName:Test) {\\\n controller->:CamelApiName:();"
-)
-CONTROLLER_REPLACEMENT_PATTERNS=(
- "FIRST\n\nSECOND"
- "FIRST\nSECOND"
- "FIRST\nSECOND"
- "FIRST\nSECOND"
- "FIRST\nSECOND"
-)
-
-# Controller shim
-CONTROLLER_SHIM=false
-CONTROLLER_SHIM_FILES=(
- "system/device/include/controller.h"
- "system/main/shim/controller.cc"
- "system/main/shim/controller.cc"
- "system/test/mock/mock_device_controller.cc"
- "system/test/mock/mock_device_controller.cc"
-)
-CONTROLLER_SHIM_FIND_PATTERNS=(
- " (\*le_rand)(LeRandCallback);"
- " bluetooth::shim::GetController()->LeRand(cb);"
- " controller_le_rand,"
- " le_rand(LeRandCallback cb) { return BTM_SUCCESS; }"
- " le_rand,"
-)
-CONTROLLER_SHIM_CODE_TEMPLATES=(
- " uint8_t (*:snake_api_name:)(void);"
- " return BTM_SUCCESS;\\\n}\\\n\\\nstatic uint8_t controller_:snake_api_name:() {\\\n bluetooth::shim::GetController()->:CamelApiName:();"
- " .:snake_api_name: = controller_:snake_api_name:"
- "tBTM_STATUS :snake_api_name:() { return BTM_SUCCESS; }"
- " :snake_api_name:,"
-)
-CONTROLLER_SHIM_REPLACEMENT_PATTERNS=(
- "FIRST\nSECOND"
- "FIRST\nSECOND"
- "FIRST\nSECOND"
- "FIRST\nSECOND"
- "FIRST\nSECOND"
-)
-
-## Files length must match templates and replacement pattern lengths!
-# BTM
-BTM_SHIM=false
-BTM_SHIM_FILES=(
- "system/main/shim/btm_api.h"
- "system/main/shim/btm_api.cc"
- "system/test/mock/mock_main_shim_btm_api.cc"
-)
-BTM_SHIM_FIND_PATTERNS=(
- "TM_STATUS BTM_LeRand(LeRandCallback);"
- "ontroller_get_interface()->le_rand(cb);"
- " bluetooth::shim::BTM_LeRand(LeRandCallback cb) {"
-)
-BTM_SHIM_CODE_TEMPLATES=(
- "\\\\\/*******************************************************************************\\\n *\\\n * Function BTM_:CamelApiName:\\\n *\\\n * Description :API_DESCRIPTION:\\\n *\\\n * Parameters\\\n *\\\n *******************************************************************************\\\\\/\\\ntBTM_STATUS BTM_:CamelApiName:(void);"
- " return BTM_SUCCESS;\\\n}\\\n\\\ntBTM_STATUS bluetooth::shim::BTM_:CamelApiName:() {\\\n \\\\\/\\\\\/PLUMB: controller_get_interface()->:snake_api_name:();"
- " inc_func_call_count(__func__);\\\n return BTM_SUCCESS;\\\n}\\\n\\\ntBTM_STATUS bluetooth::shim::BTM_:CamelApiName:() {"
-)
-BTM_SHIM_REPLACEMENT_PATTERNS=(
- "FIRST\n\nSECOND"
- "FIRST\nSECOND"
- "FIRST\nSECOND"
-)
-
-# BTA
-BTA=false
-BTA_FILES=(
- # External BTA API
- "system/bta/include/bta_api.h"
- "system/bta/dm/bta_dm_api.cc"
- # internal BTA API
- "system/bta/dm/bta_dm_int.h"
- "system/bta/dm/bta_dm_act.cc"
-)
-BTA_FIND_PATTERNS=(
- "extern void BTA_DmLeRand(LeRandCallback cb);"
- "do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_le_rand, cb));"
- "extern void bta_dm_le_rand(LeRandCallback cb);"
- "ooth::shim::BTM_LeRand(cb);"
-)
-BTA_CODE_TEMPLATES=(
- "\\\\\/*******************************************************************************\\\n *\\\n * Function BTA_Dm:CamelApiName:\\\n *\\\n * Description :API_DESCRIPTION:\\\n *\\\n * Parameters\\\n *\\\n *******************************************************************************\\\\\/\\\nextern void BTA_Dm:CamelApiName:();"
- "}\\\n\\\nvoid BTA_Dm:CamelApiName:() {\\\n APPL_TRACE_API(\"BTA_Dm:CamelApiName:\");\\\n do_in_main_thread(FROM_HERE, base::BindOnce(bta_dm_:snake_api_name:));"
- "extern void bta_dm_:snake_api_name:();"
- "}\\\n\\\n\\\\\/*******************************************************************************\\\n *\\\n * Function BTA_Dm:CamelApiName:\\\n *\\\n * Description :API_DESCRIPTION:\\\n *\\\n * Parameters\\\n *\\\n *******************************************************************************\\\\\/\\\nvoid bta_dm_:snake_api_name:() {\\\n \\\\\/\\\\\/PLUMB: bluetooth::shim::BTM_:CamelApiName:();"
-)
-BTA_REPLACEMENT_PATTERNS=(
- "FIRST\n\nSECOND"
- "FIRST\nSECOND"
- "FIRST\nSECOND"
- "FIRST\nSECOND"
-)
-
-# BTIF
-BTIF=false
-BTIF_FILES=(
- # BTIF DM Layer
- "system/btif/include/btif_dm.h"
- "system/btif/src/btif_dm.cc"
- # BTIF Layer
- "system/include/hardware/bluetooth.h"
- "system/btif/src/bluetooth.cc"
- "system/btif/src/bluetooth.cc"
- "system/service/hal/fake_bluetooth_interface.cc"
- # Yes double it for two replacements
- "system/test/mock/mock_bluetooth_interface.cc"
- "system/test/mock/mock_bluetooth_interface.cc"
-)
-BTIF_FIND_PATTERNS=(
- # BTIF DM Layer
- "oid btif_dm_le_rand(LeRandCallback callback);"
- "_dm_le_rand(callback);"
- # BTIF Layer
- "} bt_interface_t;"
- " void dump("
- " le_rand,"
- " le_rand "
- "EXPORT_SYMBOL"
- " le_rand,"
-)
-BTIF_CODE_TEMPLATES=(
- # BTIF DM Layer
- " void btif_dm_:snake_api_name:();"
- "}\\\n\\\nvoid btif_dm_:snake_api_name:() {\\\n \\\\\/\\\\\/PLUMB: BTA_Dm:CamelApiName:();"
- # BTIF Layer
- " \\\n\\\\\/**\\\n *\\\n * :API_DESCRIPTION:\\\n *\\\n *\\\\\/\\\nint (*:snake_api_name:)();"
- " int :snake_api_name:() {\\\n if(!interface_ready()) return BT_STATUS_NOT_READY;\\\n do_in_main_thread(FROM_HERE, base::BindOnce(btif_dm_:snake_api_name:));\\\n return BT_STATUS_SUCCESS;\\\n}\\\n\\\nstatic"
- "\ \ \ \ :snake_api_name:,"
- "*\\\\\/\\\n\ \ \ \ nullptr, \\\\\/* :snake_api_name: "
- "static int :snake_api_name:() { return 0; }\\\n\\\nE"
- "\ \ \ \ :snake_api_name:,"
-)
-BTIF_REPLACEMENT_PATTERNS=(
- # BTIF DM Layer
- "FIRST\nSECOND"
- "FIRST\nSECOND"
- # BTIF Layer
- "SECOND\nFIRST"
- "SECONDFIRST"
- "FIRST\nSECOND"
- "FIRSTSECOND"
- "SECONDFIRST"
- "FIRST\nSECOND"
-)
-
-# Topshim
-TOPSHIM=false
-TOPSHIM_FILES=(
- # Topshim API
- "system/gd/rust/topshim/src/btif.rs"
- "system/gd/rust/topshim/facade/src/adapter_service.rs"
- # Topshim Test API
- "system/blueberry/facade/topshim/facade.proto"
- "system/blueberry/tests/gd/rust/topshim/facade/automation_helper.py"
-)
-TOPSHIM_FIND_PATTERNS=(
- # Topshim API
- " le_rand)"
- ".le_rand();"
- # Topshim Test API
- " LeRand(google.protobuf.Empty) returns (google.protobuf.Empty) {}"
- " self.adapter_stub.LeRand(empty_proto.Empty())"
-)
-TOPSHIM_CODE_TEMPLATES=(
- # Topshim API
- " }\\\n\\\n pub fn :snake_api_name:(\\\\\&self) -> i32 {\\\n ccall!(self, :snake_api_name:)"
- " ctx.spawn(async move {\\\n sink.success(Empty::default()).await.unwrap();\\\n })\\\n }\\\n\\\n fn :snake_api_name:(\\\\\&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>) {\\\n self.btif_intf.lock().unwrap().:snake_api_name:();"
- # Topshim Test API
- " rpc :CamelApiName:(google.protobuf.Empty) returns (google.protobuf.Empty) {}"
- " async def :snake_api_name:(self):\\\n await self.adapter_stub.:CamelApiName:(empty_proto.Empty())"
-)
-TOPSHIM_REPLACEMENT_PATTERNS=(
- "FIRST\nSECOND"
- "FIRST\nSECOND"
- "FIRST\nSECOND"
- "FIRST\n\nSECOND"
-)
-
-function help_menu {
- echo
- echo -e "${YELLOW}Help menu${NOCOLOR}"
- echo -e "==================================="
- echo -e "${BLUE} --controller${NOCOLOR}"
- echo -e " Adds plumbing for the GD Controller Layer for the API."
- echo -e " This includes test file changes required to build."
- echo -e "${BLUE} --controller-shim${NOCOLOR}"
- echo -e " Adds plumbing for the GD Controller Shim Layer for the API."
- echo -e " This includes test file changes required to build."
- echo -e " Will autoplumb to ONLY the GD controller if --controller flag is set. (as opposed to legacy controller btu_hcif)"
- echo -e "${BLUE} --btm${NOCOLOR}"
- echo -e " Adds plumbing for the BTM Shim Layer for the given API."
- echo -e " Will autoplumb to ONLY the controller shim if --controller-shim flag is set. vs directly to legacy btu_hcif"
- echo -e "${BLUE} --bta${NOCOLOR}"
- echo -e " Adds plumbing for the BTA Layer for the given API."
- echo -e " Will autoplumb to BTM if --btm set."
- echo -e "${BLUE} --btif${NOCOLOR}"
- echo -e " Adds plumbing for the BTIF Layer for the API."
- echo -e " This currently includes JNI as it is a requirement for Android to build."
- echo -e " Will autoplumb to BTA if --bta set."
- echo -e "${BLUE} --topshim${NOCOLOR}"
- echo -e " Adds plumbing for the topshim to BTIF Layer for the API."
- echo -e " This will also include testing APIs callable from python tests."
- echo -e " Will autoplumb to BTIF if --btif set."
- echo -e "${BLUE} --verbose${NOCOLOR}"
- echo -e " Prints verbose logging."
- echo
- echo -e "Usage: $0 [--controller|--controller-shim|--btm|--bta|--btif|--topshim] [CamelCaseApiName] [snake_case_api_name] (description)"
- echo -e " ${YELLOW}e.g."
- echo -e " $0 --controller --btm ClearEventMask clear_event_mask \"Clear out the event mask\""
- echo -e " $0 --controller --btm --bta --btif --topshim ClearEventMaskclear_event_mask \"Clear out the event mask\" ${NOCOLOR}"
- echo
-}
-
-## Start parsing arguments here
-POSITIONAL=()
-function parse_options {
- while [[ $# -gt 0 ]]
- do
- key="$1"
- case $key in
- --verbose)
- VERBOSE=true
- shift
- ;;
- --help)
- help_menu
- shift
- exit 0
- ;;
- --controller)
- CONTROLLER=true
- shift
- ;;
- --controller-shim)
- CONTROLLER_SHIM=true
- shift
- ;;
- --btm)
- # Actually we skip BTM here and just use the BTM Shim
- BTM_SHIM=true
- shift
- ;;
- --bta)
- BTA=true
- shift
- ;;
- --btif)
- BTIF=true
- shift
- ;;
- --topshim)
- TOPSHIM=true
- shift
- ;;
- --*)
- echo "$0: unrecognized argument: '$1'"
- echo "Try '$0 --help' for more information"
- exit 1
- shift
- ;;
- *)
- POSITIONAL+=("${1}")
- shift
- ;;
- esac
- done
- set -- "${POSITIONAL[@]}"
-}
-
-function show_mario {
- MSG="$(mario_message)I'm plumbing the '${1}'"
- echo
- echo -e "${RED} ⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣠⣤⣤⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ "⠀
- echo -e "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⡾⣻⣿⣿⣿⣿⣯⣍⠛⠻⢷⣦⣀⠀⠀⠀⠀⠀⠀⠀ "
- echo -e "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⠟⢁⣾⠟⠋⣁⣀⣤⡉⠻⣷⡀⠀⠙⢿⣷⣄⠀⠀⠀⠀⠀ "⠀
- echo -e "${NOCOLOR}⠀⠀⠀⠀⠀⠀⠀⢀⡀${RED}⠀⠀⠀⠀⠀⠀⣰⣿⠏⠀⠀⢸⣿⠀⠼⢋⣉⣈⡳⢀⣿⠃⠀⠀⠀⠙⣿⣦⡀⠀⠀⠀ "⠀
- echo -e "${NOCOLOR}⠀⠀⠀⠀⠀⠀⢰⡿⠿⣷⡀⠀${RED}⠀⠀⣼⣿⠃⠀⠀⣀⣤⡿⠟⠛⠋⠉⠉⠙⢛⣻⠶⣦⣄⡀⠀⠘⣿⣷⡀⠀⠀ "⠀
- echo -e "${NOCOLOR}⢠⣾⠟⠳⣦⣄⢸⡇⠀⠈⣷⡀${RED}⠀⣼⣿⡏⢀⣤⡾${NOCOLOR}⢋⣵⠿⠻⢿⠋⠉⠉⢻⠟⠛⠻⣦⣝${RED}⠻⣷⣄⠸⣿⣿${NOCOLOR}⠀⠀ ( ${MSG} )"⠀
- echo -e "⠘⣧⠀⠀⠀⠙⢿⣿⠀⠀⢸⣷${RED}⠀⣿⣿⣧⣾⣏${NOCOLOR}⡴⠛⢡⠖⢛⣲⣅⠀⠀⣴⣋⡉⠳⡄⠈⠳${RED}⢬⣿⣿⣿⡿${NOCOLOR}⠀⠀ O"⠀
- echo -e "⠀⠘⠷⣤⣀⣀⣀⣽⡶⠛⠛⠛⢷⣿⣿⣿⣿⣏⠀⠀⡏⢰⡿⢿⣿⠀⠀⣿⠻⣿⠀⡷⠀⣠⣾⣿⡿⠛⠷⣦⠀ o"⠀
- echo -e "⠀⠀⢀⣾⠟⠉⠙⣿⣤⣄⠀⢀⣾⠉⠀⢹⣿⣿⣷⠀⠹⡘⣷⠾⠛⠋⠉⠛⠻⢿⡴⢃⣄⣻⣿⣿⣷⠀⠀⢹⡇ ."⠀
- echo -e "⠀⠀⢸⡇⠈⠉⠛⢦⣿⡏⠀⢸⣧⠀⠈⠻⣿⡿⢣⣾⣦⣽⠃⠀⠀⠀⠀⠀⠀⠀⣷⣾⣿⡇⠉⢿⡇⠀⢀⣼⠇ "⠀
- echo -e "⠀⠀⠘⣷⡠⣄⣀⣼⠇⠀⠀⠀⠻⣷⣤⣀⣸⡇⠀⠹⣿⣿⣦⣀⠀⠀⠀⠀⢀⣴⣿⣿⡟⠀⠀⢸⣷⣾⡿⠃⠀ "⠀
- echo -e "⠀⠀⠀⠈⠻⢦⣍⣀⣀⣀⡄⠀⣰⣿⡿⠿⢿⣇⠀⠀⠉⠛⠻⣿⣿⡷⠾⣿⣿⡿⠉⠁⠀⠀⢀⣾⠋⠁⠀⠀⠀ "
- echo -e "⠀⠀⠀⠀⠀⠀⠈⠉⠉⠙⠿⢿⣿⣇⠀⠀⠈⢿⣧⣄⠀⠀⠀⢹⣷⣶⣶⣾⣿⡇⠀⠀⣀⣴⡿⣧⣄⡀⠀⠀⠀ "⠀
- echo -e "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣷⡀⠀⠀⠙⢿⣿⣶⣤⡀⠻⢤⣀⡤⠞⢀⣴⣿⣿⠟⢷⡀⠙⠻⣦⣄⠀ "⠀
- echo -e "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⣦⠀⢠⡟⠁⠙⢻⣿⠷⠶⣶⠶⠾⠛⠙⣿⠇⠀⠀⢻⡄⠀⠀⠙⢷⡀ "
- echo -e "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⡀⣿⠁⣤⣤⡄⢻⡶⠶⠛⠛⠛⠛⠛⣿⢠⣾⣷⣆⢻⡀⠀⠀⠈⣷ "
- echo -e "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⢸⣿⣿⣿⡈⢿⡀⠀⠀⠀⠀⠀⡿⢸⣿⣿⣿⢸⡇⠀⠀⠀⡟ "
- echo -e "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠉⠈⠉⠉⠉⠁⠈⠁⠀⠀⠀⠀⠈⠁⠈⠉⠉⠉⠀⠁⠀⠀⠈⠁ "
- echo
-}
-
-function mario_done {
- echo -e "${YELLOW}Done.${NOCOLOR}"
-}
-
-function mario_message {
- I=$((0 + $RANDOM % ${#QUOTES[@]}))
- echo -en "${BLUE}${QUOTES[$I]}! ${BLUE}${2}${YELLOW}${1} ${NOCOLOR}"
-}
-
-# TODO: Pass in which patterns and templates to use
-function plumbit {
- layer="$1"
- shift
- camel_api_name="$1"
- shift
- snake_api_name="$1"
- shift
- api_description="$1"
- shift
- files_array=($@)
-
- WORKING_CODE_TEMPLATES=()
- WORKING_PATTERNS=()
- AUTOPLUMB=false
- if [ "$layer" == "controller" ]; then
- WORKING_PATTERNS=("${CONTROLLER_FIND_PATTERNS[@]}")
- WORKING_CODE_TEMPLATES=("${CONTROLLER_CODE_TEMPLATES[@]}")
- WORKING_REPLACEMENTS=("${CONTROLLER_REPLACEMENT_PATTERNS[@]}")
- elif [ "$layer" == "controller_shim" ]; then
- WORKING_PATTERNS=("${CONTROLLER_SHIM_FIND_PATTERNS[@]}")
- WORKING_CODE_TEMPLATES=("${CONTROLLER_SHIM_CODE_TEMPLATES[@]}")
- WORKING_REPLACEMENTS=("${CONTROLLER_SHIM_REPLACEMENT_PATTERNS[@]}")
- AUTOPLUMB=$CONTROLLER
- elif [ "$layer" == "btm_shim" ]; then
- WORKING_PATTERNS=("${BTM_SHIM_FIND_PATTERNS[@]}")
- WORKING_CODE_TEMPLATES=("${BTM_SHIM_CODE_TEMPLATES[@]}")
- WORKING_REPLACEMENTS=("${BTM_SHIM_REPLACEMENT_PATTERNS[@]}")
- AUTOPLUMB=$CONTROLLER_SHIM
- elif [ "$layer" == "bta" ]; then
- WORKING_PATTERNS=("${BTA_FIND_PATTERNS[@]}")
- WORKING_CODE_TEMPLATES=("${BTA_CODE_TEMPLATES[@]}")
- WORKING_REPLACEMENTS=("${BTA_REPLACEMENT_PATTERNS[@]}")
- AUTOPLUMB=$BTM_SHIM
- elif [ "$layer" == "btif" ]; then
- WORKING_PATTERNS=("${BTIF_FIND_PATTERNS[@]}")
- WORKING_CODE_TEMPLATES=("${BTIF_CODE_TEMPLATES[@]}")
- WORKING_REPLACEMENTS=("${BTIF_REPLACEMENT_PATTERNS[@]}")
- AUTOPLUMB=$BTA
- elif [ "$layer" == "topshim" ]; then
- WORKING_PATTERNS=("${TOPSHIM_FIND_PATTERNS[@]}")
- WORKING_CODE_TEMPLATES=("${TOPSHIM_CODE_TEMPLATES[@]}")
- WORKING_REPLACEMENTS=("${TOPSHIM_REPLACEMENT_PATTERNS[@]}")
- AUTOPLUMB=$BTIF
- fi
-
- for index in ${!files_array[@]}; do
- CODE=$(echo "${WORKING_CODE_TEMPLATES[$index]}" | sed "s/:CamelApiName:/$camel_api_name/g" | sed "s/:snake_api_name:/$snake_api_name/g" | sed "s/WHOAMI/$(whoami)/g" | sed "s/:API_DESCRIPTION:/${api_description}/g")
- if [ "$AUTOPLUMB" == true ]; then
- CODE=$(echo "${CODE}" | sed "s/PLUMB:/ Autoplumbed\\\\\\\n /g")
- fi
- PATTERN="${WORKING_PATTERNS[$index]}"
- REPLACEMENT=$(echo ${WORKING_REPLACEMENTS[$index]} | sed s/FIRST/"\\${PATTERN}"/g | sed s/SECOND/"${CODE}"/g)
- if [ "$VERBOSE" == true ]; then
- echo sed -i "s/\\${PATTERN}/\\${REPLACEMENT}/g" "${files_array[$index]}"
- fi
- sed -i "s/\\${PATTERN}/\\${REPLACEMENT}/g" "${files_array[$index]}"
- done
-}
-
-CL_COUNT=0
-
-function commitit {
- mario_message "${1}" "Committing the code..."
- git commit -qam "${2} ${1} API"
- mario_done
- let CL_COUNT=$CL_COUNT+1
-}
-
-function clangit {
- FORMATTER="${ANDROID_BUILD_TOP}/tools/repohooks/tools/clang-format.py"
- FIX="--fix"
- CLANG_FORMAT="--clang-format ${ANDROID_BUILD_TOP}/prebuilts/clang/host/linux-x86/clang-stable/bin/clang-format"
- GIT_CLANG_FORMAT="--git-clang-format ${ANDROID_BUILD_TOP}/prebuilts/clang/host/linux-x86/clang-stable/bin/git-clang-format"
- COMMIT="--commit"
- STYLE="--style file"
- EXTENSIONS="--extensions c,h,cc,cpp,hpp"
- HASH="$1"
- CMD="${FORMATTER} ${FIX} ${CLANG_FORMAT} ${GIT_CLANG_FORMAT} ${COMMIT} ${HASH} ${STYLE} ${EXTENSIONS}"
- $(${CMD})
-}
-
-function rustfmtit {
- echo "rusty rust"
-# FORMATTER="${ANDROID_BUILD_TOP}/prebuilts/rust/linux-x86/stable/rustfmt"
-# CONFIG="'--config-path=rustfmt.toml'"
-# FILE=""
-# CMD="${FORMATTER} ${CONFIG} ${FILE}"
-# $(${CMD})
-}
-
-
-function formatit {
- mario_message "${1}" "Formatting the code..."
- hash="$(git log -n 1 --pretty=oneline | awk '{ print $1 }')"
- clangit $hash
- rustfmtit $hash
- git commit -a --amend --no-edit
- mario_done
-}
-
-function controller {
- if [ "$CONTROLLER" == false ]; then
- return
- fi
- mario_message "Controller" "Plumbing the '${1}' API..."
- plumbit "controller" "${1}" "${2}" "${3}" "${CONTROLLER_FILES[@]}"
- mario_done
- commitit "Controller" "${3}"
- formatit "Controller"
-}
-
-function controller_shim {
- if [ "$CONTROLLER_SHIM" == false ]; then
- return
- fi
- mario_message "Controller shim" "Plumbing the '${1}' API..."
- plumbit "controller_shim" "${1}" "${2}" "${3}" "${CONTROLLER_SHIM_FILES[@]}"
- mario_done
- commitit "Controller shim" "${3}"
- formatit "Controller shim"
-}
-
-function btm_shim {
- if [ "$BTM_SHIM" == false ]; then
- return
- fi
- mario_message "BTM" "Plumbing the '${1}' API..."
- plumbit "btm_shim" "${1}" "${2}" "${3}" "${BTM_SHIM_FILES[@]}"
- mario_done
- commitit "BTM" "${3}"
- formatit "BTM"
-}
-
-function bta {
- if [ "$BTA" == false ]; then
- return
- fi
- mario_message "BTA" "Plumbing the '${1}' API..."
- plumbit "bta" "${1}" "${2}" "${3}" "${BTA_FILES[@]}"
- mario_done
- commitit "BTA" "${3}"
- formatit "BTA"
-}
-
-function btif {
- if [ "$BTIF" == false ]; then
- return
- fi
- mario_message "BTIF" "Plumbing the '${1}' API..."
- plumbit "btif" "${1}" "${2}" "${3}" "${BTIF_FILES[@]}"
- mario_done
- commitit "BTIF" "${3}"
- formatit "BTIF"
-}
-
-function topshim {
- if [ "$TOPSHIM" == false ]; then
- return
- fi
- mario_message "Topshim" "Plumbing the '${1}' API..."
- plumbit "topshim" "${1}" "${2}" "${3}" "${TOPSHIM_FILES[@]}"
- mario_done
- commitit "Topshim" "${3}"
- formatit "Topshim"
-}
-
-function main {
- check_environment
- parse_options $@
- if [ "${#POSITIONAL[@]}" -lt 3 ]; then
- echo -e "${RED}Error: Invalid argument count for API Names!${NOCOLOR}"
- help_menu
- exit 1
- fi
- camel_api_name="${POSITIONAL[0]}"
- snake_api_name="${POSITIONAL[1]}"
- api_description="${POSITIONAL[@]:2}"
- show_mario "${camel_api_name} API that ${api_description}!"
- controller "${camel_api_name}" "${snake_api_name}" "${api_description}"
- controller_shim "${camel_api_name}" "${snake_api_name}" "${api_description}"
- btm_shim "${camel_api_name}" "${snake_api_name}" "${api_description}"
- bta "${camel_api_name}" "${snake_api_name}" "${api_description}"
- btif "${camel_api_name}" "${snake_api_name}" "${api_description}"
- topshim "${camel_api_name}" "${snake_api_name}" "${api_description}"
- git rebase -i HEAD~${CL_COUNT} -x 'git commit --amend'
-}
-
-main $@
-#/usr/local/google/home/optedoblivion/workspace/AOSP/prebuilts/rust/linux-x86/stable/rustfmt '--config-path=rustfmt.toml' system/gd/rust/topshim/facade/src/adapter_service.rs
diff --git a/tools/rootcanal/Android.bp b/tools/rootcanal/Android.bp
index 188f425bd0..67dd3afa78 100644
--- a/tools/rootcanal/Android.bp
+++ b/tools/rootcanal/Android.bp
@@ -135,7 +135,6 @@ cc_library_static {
static_libs: [
"libscriptedbeaconpayload-protos-lite",
],
- include_dirs: ["packages/modules/Bluetooth/system/gd"],
}
// This library implements a foreigh function interface over DualModeController
@@ -179,7 +178,6 @@ cc_library_host_shared {
cflags: [
"-fexceptions",
],
- include_dirs: ["packages/modules/Bluetooth/system/gd"],
}
// Generate the python parser+serializer backend for
@@ -223,7 +221,7 @@ genrule {
" $(location :pdl_python_generator)" +
" --output $(out) --custom-type-location py.bluetooth",
srcs: [
- "packets/hci/hci_packets.pdl",
+ "packets/hci_packets.pdl",
],
out: [
"hci_packets.py",
@@ -293,7 +291,6 @@ cc_test_host {
static_libs: [
"libbt-rootcanal",
],
- include_dirs: ["packages/modules/Bluetooth/system/gd"],
}
// Implement the Bluetooth official LL test suite for root-canal.
@@ -313,8 +310,8 @@ python_test_host {
"test/LL/CON_/PER/*.py",
"test/LL/DDI/ADV/*.py",
"test/LL/DDI/SCN/*.py",
- "test/LMP/LIH/*.py",
"test/LMP/*.py",
+ "test/LMP/LIH/*.py",
"test/main.py",
],
data: [
@@ -367,7 +364,6 @@ cc_test_host {
enabled: false,
},
},
- include_dirs: ["packages/modules/Bluetooth/system/gd"],
}
// Linux RootCanal Executable
@@ -409,14 +405,13 @@ cc_binary_host {
enabled: false,
},
},
- include_dirs: ["packages/modules/Bluetooth/system/gd"],
}
genrule {
name: "rootcanal_hci_packets_cxx_gen",
tools: [
- ":pdlc",
":pdl_cxx_generator",
+ ":pdlc",
],
cmd: "set -o pipefail;" +
" $(location :pdlc) $(in) |" +
@@ -425,7 +420,7 @@ genrule {
" --include-header hci/address.h" +
" --output $(out)",
srcs: [
- "packets/hci/hci_packets.pdl",
+ "packets/hci_packets.pdl",
],
out: [
"packets/hci_packets.h",
@@ -435,8 +430,8 @@ genrule {
genrule {
name: "rootcanal_link_layer_packets_cxx_gen",
tools: [
- ":pdlc",
":pdl_cxx_generator",
+ ":pdlc",
],
cmd: "set -o pipefail;" +
" $(location :pdlc) $(in) |" +
@@ -456,8 +451,8 @@ genrule {
genrule {
name: "rootcanal_bredr_bb_packets_cxx_gen",
tools: [
- ":pdlc",
":pdl_cxx_generator",
+ ":pdlc",
],
cmd: "set -o pipefail;" +
" $(location :pdlc) $(in) |" +
@@ -477,6 +472,6 @@ genrule {
genrule {
name: "rootcanal_hci_packets_rust_gen",
defaults: ["pdl_rust_generator_defaults"],
- srcs: ["packets/hci/hci_packets.pdl"],
+ srcs: ["packets/hci_packets.pdl"],
out: ["hci_packets.rs"],
}
diff --git a/tools/rootcanal/CMakeLists.txt b/tools/rootcanal/CMakeLists.txt
index 91e3d7ff0e..53aec54b73 100644
--- a/tools/rootcanal/CMakeLists.txt
+++ b/tools/rootcanal/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(BT_ROOT ${AOSP_ROOT}/packages/modules/Bluetooth/system)
+set(BT_ROOT ${AOSP_ROOT}/packages/modules/Bluetooth)
set(ROOTCANAL_ROOT ${AOSP_ROOT}/packages/modules/Bluetooth/tools/rootcanal)
set(PDL_ROOT ${AOSP_ROOT}/external/rust/crates/pdl-compiler)
@@ -109,7 +109,7 @@ endfunction()
pdl_gen(
NAME BluetoothGeneratedPackets_h
- INPUT ${ROOTCANAL_ROOT}/packets/hci/hci_packets.pdl
+ INPUT ${ROOTCANAL_ROOT}/packets/hci_packets.pdl
OUTPUT packets/hci_packets.h
LANG c++
NAMESPACE "bluetooth::hci"
@@ -166,7 +166,7 @@ target_include_directories(libbt-rootcanal.headers INTERFACE ${ROOTCANAL_ROOT})
target_link_libraries(libbt-rootcanal.headers
INTERFACE android-emu-base-headers)
android_license(TARGET "libbt-rootcanal.headers" LIBNAME None SPDX Apache-2.0
- LICENSE Apache-2.0 LOCAL "${BT_ROOT}/../NOTICE")
+ LICENSE Apache-2.0 LOCAL "${BT_ROOT}/NOTICE")
android_add_library(
TARGET librootcanal_log
diff --git a/tools/rootcanal/hal/bluetooth_hci.cc b/tools/rootcanal/hal/bluetooth_hci.cc
index bab7be1139..d63b870843 100644
--- a/tools/rootcanal/hal/bluetooth_hci.cc
+++ b/tools/rootcanal/hal/bluetooth_hci.cc
@@ -69,7 +69,7 @@ class BluetoothDeathRecipient : public hidl_death_recipient {
void setHasDied(bool has_died) { has_died_ = has_died; }
private:
- bool has_died_;
+ bool has_died_{false};
};
BluetoothHci::BluetoothHci()
diff --git a/tools/rootcanal/model/controller/dual_mode_controller.cc b/tools/rootcanal/model/controller/dual_mode_controller.cc
index 346d0debd7..d2b8780c05 100644
--- a/tools/rootcanal/model/controller/dual_mode_controller.cc
+++ b/tools/rootcanal/model/controller/dual_mode_controller.cc
@@ -2055,10 +2055,10 @@ void DualModeController::LeCreateConnection(CommandView command) {
command_view.GetPeerAddress(),
command_view.GetPeerAddressType(),
},
- command_view.GetOwnAddressType(), command_view.GetConnIntervalMin(),
- command_view.GetConnIntervalMax(), command_view.GetConnLatency(),
- command_view.GetSupervisionTimeout(), command_view.GetMinimumCeLength(),
- command_view.GetMaximumCeLength());
+ command_view.GetOwnAddressType(), command_view.GetConnectionIntervalMin(),
+ command_view.GetConnectionIntervalMax(), command_view.GetMaxLatency(),
+ command_view.GetSupervisionTimeout(), command_view.GetMinCeLength(),
+ command_view.GetMaxCeLength());
send_event_(bluetooth::hci::LeCreateConnectionStatusBuilder::Create(
status, kNumCommandPackets));
}
@@ -2083,8 +2083,9 @@ void DualModeController::LeConnectionUpdate(CommandView command) {
DEBUG(id_, " connection_handle=0x{:x}", command_view.GetConnectionHandle());
ErrorCode status = link_layer_controller_.LeConnectionUpdate(
- command_view.GetConnectionHandle(), command_view.GetConnIntervalMin(),
- command_view.GetConnIntervalMax(), command_view.GetConnLatency(),
+ command_view.GetConnectionHandle(),
+ command_view.GetConnectionIntervalMin(),
+ command_view.GetConnectionIntervalMax(), command_view.GetMaxLatency(),
command_view.GetSupervisionTimeout());
send_event_(bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
@@ -2602,7 +2603,7 @@ void DualModeController::LeSetExtendedScanParameters(CommandView command) {
ErrorCode status = link_layer_controller_.LeSetExtendedScanParameters(
command_view.GetOwnAddressType(), command_view.GetScanningFilterPolicy(),
- command_view.GetScanningPhys(), command_view.GetParameters());
+ command_view.GetScanningPhys(), command_view.GetScanningPhyParameters());
send_event_(
bluetooth::hci::LeSetExtendedScanParametersCompleteBuilder::Create(
kNumCommandPackets, status));
@@ -2633,18 +2634,30 @@ void DualModeController::LeExtendedCreateConnection(CommandView command) {
DEBUG(id_, "<< LE Extended Create Connection");
DEBUG(id_, " peer_address={}", command_view.GetPeerAddress());
DEBUG(id_, " peer_address_type={}",
- bluetooth::hci::AddressTypeText(command_view.GetPeerAddressType()));
+ bluetooth::hci::PeerAddressTypeText(command_view.GetPeerAddressType()));
DEBUG(id_, " initiator_filter_policy={}",
bluetooth::hci::InitiatorFilterPolicyText(
command_view.GetInitiatorFilterPolicy()));
+ AddressType peer_address_type;
+ switch (command_view.GetPeerAddressType()) {
+ case PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS:
+ default:
+ peer_address_type = AddressType::PUBLIC_DEVICE_ADDRESS;
+ break;
+ case PeerAddressType::RANDOM_DEVICE_OR_IDENTITY_ADDRESS:
+ peer_address_type = AddressType::RANDOM_DEVICE_ADDRESS;
+ break;
+ }
+
ErrorCode status = link_layer_controller_.LeExtendedCreateConnection(
command_view.GetInitiatorFilterPolicy(), command_view.GetOwnAddressType(),
AddressWithType{
command_view.GetPeerAddress(),
- command_view.GetPeerAddressType(),
+ peer_address_type,
},
- command_view.GetInitiatingPhys(), command_view.GetPhyScanParameters());
+ command_view.GetInitiatingPhys(),
+ command_view.GetInitiatingPhyParameters());
send_event_(bluetooth::hci::LeExtendedCreateConnectionStatusBuilder::Create(
status, kNumCommandPackets));
}
diff --git a/tools/rootcanal/model/controller/link_layer_controller.cc b/tools/rootcanal/model/controller/link_layer_controller.cc
index 96e3bfe845..ed92bc1f71 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;
}
@@ -1281,7 +1281,8 @@ ErrorCode LinkLayerController::LeSetExtendedScanParameters(
bluetooth::hci::OwnAddressType own_address_type,
bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy,
uint8_t scanning_phys,
- std::vector<bluetooth::hci::PhyScanParameters> scanning_phy_parameters) {
+ std::vector<bluetooth::hci::ScanningPhyParameters>
+ scanning_phy_parameters) {
uint8_t supported_phys = properties_.LeSupportedPhys();
// Extended advertising commands are disallowed when legacy advertising
@@ -1676,7 +1677,7 @@ ErrorCode LinkLayerController::LeExtendedCreateConnection(
bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy,
bluetooth::hci::OwnAddressType own_address_type,
AddressWithType peer_address, uint8_t initiating_phys,
- std::vector<bluetooth::hci::LeCreateConnPhyScanParameters>
+ std::vector<bluetooth::hci::InitiatingPhyParameters>
initiating_phy_parameters) {
// Extended advertising commands are disallowed when legacy advertising
// commands were used since the last reset.
@@ -1751,36 +1752,39 @@ ErrorCode LinkLayerController::LeExtendedCreateConnection(
// Note: no explicit error code stated for invalid connection interval
// values but assuming Unsupported Feature or Parameter Value (0x11)
// error code based on similar advertising command.
- if (parameter.conn_interval_min_ < 0x6 ||
- parameter.conn_interval_min_ > 0x0c80 ||
- parameter.conn_interval_max_ < 0x6 ||
- parameter.conn_interval_max_ > 0x0c80) {
+ if (parameter.connection_interval_min_ < 0x6 ||
+ parameter.connection_interval_min_ > 0x0c80 ||
+ parameter.connection_interval_max_ < 0x6 ||
+ parameter.connection_interval_max_ > 0x0c80) {
INFO(id_,
"connection_interval_min (0x{:04x}) and/or "
"connection_interval_max (0x{:04x}) are outside the range"
" of supported values (0x6 - 0x0c80)",
- parameter.conn_interval_min_, parameter.conn_interval_max_);
+ parameter.connection_interval_min_,
+ parameter.connection_interval_max_);
return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
}
// The Connection_Interval_Min parameter shall not be greater than the
// Connection_Interval_Max parameter.
- if (parameter.conn_interval_max_ < parameter.conn_interval_min_) {
+ if (parameter.connection_interval_max_ <
+ parameter.connection_interval_min_) {
INFO(id_,
"connection_interval_min (0x{:04x}) is larger than"
" connection_interval_max (0x{:04x})",
- parameter.conn_interval_min_, parameter.conn_interval_max_);
+ parameter.connection_interval_min_,
+ parameter.connection_interval_max_);
return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
}
// Note: no explicit error code stated for invalid max_latency
// values but assuming Unsupported Feature or Parameter Value (0x11)
// error code based on similar advertising command.
- if (parameter.conn_latency_ > 0x01f3) {
+ if (parameter.max_latency_ > 0x01f3) {
INFO(id_,
"max_latency (0x{:04x}) is outside the range"
" of supported values (0x0 - 0x01f3)",
- parameter.conn_latency_);
+ parameter.max_latency_);
return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
}
@@ -1800,8 +1804,8 @@ ErrorCode LinkLayerController::LeExtendedCreateConnection(
// (1 + Max_Latency) * Connection_Interval_Max * 2, where
// Connection_Interval_Max is given in milliseconds.
milliseconds min_supervision_timeout = duration_cast<milliseconds>(
- (1 + parameter.conn_latency_) *
- slots(2 * parameter.conn_interval_max_) * 2);
+ (1 + parameter.max_latency_) *
+ slots(2 * parameter.connection_interval_max_) * 2);
if (parameter.supervision_timeout_ * 10ms < min_supervision_timeout) {
INFO(
id_,
@@ -1862,10 +1866,10 @@ ErrorCode LinkLayerController::LeExtendedCreateConnection(
.scan_interval = initiating_phy_parameters[offset].scan_interval_,
.scan_window = initiating_phy_parameters[offset].scan_window_,
.connection_interval_min =
- initiating_phy_parameters[offset].conn_interval_min_,
+ initiating_phy_parameters[offset].connection_interval_min_,
.connection_interval_max =
- initiating_phy_parameters[offset].conn_interval_max_,
- .max_latency = initiating_phy_parameters[offset].conn_latency_,
+ initiating_phy_parameters[offset].connection_interval_max_,
+ .max_latency = initiating_phy_parameters[offset].max_latency_,
.supervision_timeout =
initiating_phy_parameters[offset].supervision_timeout_,
.min_ce_length = initiating_phy_parameters[offset].min_ce_length_,
@@ -1880,10 +1884,10 @@ ErrorCode LinkLayerController::LeExtendedCreateConnection(
.scan_interval = initiating_phy_parameters[offset].scan_interval_,
.scan_window = initiating_phy_parameters[offset].scan_window_,
.connection_interval_min =
- initiating_phy_parameters[offset].conn_interval_min_,
+ initiating_phy_parameters[offset].connection_interval_min_,
.connection_interval_max =
- initiating_phy_parameters[offset].conn_interval_max_,
- .max_latency = initiating_phy_parameters[offset].conn_latency_,
+ initiating_phy_parameters[offset].connection_interval_max_,
+ .max_latency = initiating_phy_parameters[offset].max_latency_,
.supervision_timeout =
initiating_phy_parameters[offset].supervision_timeout_,
.min_ce_length = initiating_phy_parameters[offset].min_ce_length_,
@@ -1898,10 +1902,10 @@ ErrorCode LinkLayerController::LeExtendedCreateConnection(
.scan_interval = initiating_phy_parameters[offset].scan_interval_,
.scan_window = initiating_phy_parameters[offset].scan_window_,
.connection_interval_min =
- initiating_phy_parameters[offset].conn_interval_min_,
+ initiating_phy_parameters[offset].connection_interval_min_,
.connection_interval_max =
- initiating_phy_parameters[offset].conn_interval_max_,
- .max_latency = initiating_phy_parameters[offset].conn_latency_,
+ initiating_phy_parameters[offset].connection_interval_max_,
+ .max_latency = initiating_phy_parameters[offset].max_latency_,
.supervision_timeout =
initiating_phy_parameters[offset].supervision_timeout_,
.min_ce_length = initiating_phy_parameters[offset].min_ce_length_,
@@ -2833,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) {
@@ -3280,6 +3288,7 @@ void LinkLayerController::ConnectIncomingLeLegacyAdvertisingPdu(
}
initiator_.pending_connect_request = advertising_address;
+ initiator_.initiating_address = initiating_address.GetAddress();
INFO(id_, "Sending LE Connect request to {} with initiating address {}",
resolved_advertising_address, initiating_address);
@@ -3706,6 +3715,7 @@ void LinkLayerController::ConnectIncomingLeExtendedAdvertisingPdu(
}
initiator_.pending_connect_request = advertising_address;
+ initiator_.initiating_address = initiating_address.GetAddress();
INFO(id_, "Sending LE Connect request to {} with initiating address {}",
resolved_advertising_address, initiating_address);
diff --git a/tools/rootcanal/model/controller/link_layer_controller.h b/tools/rootcanal/model/controller/link_layer_controller.h
index c028424885..2e426a86fb 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, uint32_t id = 0);
~LinkLayerController();
@@ -480,7 +483,8 @@ class LinkLayerController {
bluetooth::hci::OwnAddressType own_address_type,
bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy,
uint8_t scanning_phys,
- std::vector<bluetooth::hci::PhyScanParameters> scanning_phy_parameters);
+ std::vector<bluetooth::hci::ScanningPhyParameters>
+ scanning_phy_parameters);
// HCI command LE_Set_Extended_Scan_Enable (Vol 4, Part E § 7.8.65).
ErrorCode LeSetExtendedScanEnable(
@@ -509,7 +513,7 @@ class LinkLayerController {
bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy,
bluetooth::hci::OwnAddressType own_address_type,
AddressWithType peer_address, uint8_t initiating_phys,
- std::vector<bluetooth::hci::LeCreateConnPhyScanParameters>
+ std::vector<bluetooth::hci::InitiatingPhyParameters>
initiating_phy_parameters);
// Periodic Advertising
diff --git a/tools/rootcanal/model/devices/hci_device.cc b/tools/rootcanal/model/devices/hci_device.cc
index 50263a0de7..710bd3a598 100644
--- a/tools/rootcanal/model/devices/hci_device.cc
+++ b/tools/rootcanal/model/devices/hci_device.cc
@@ -54,30 +54,38 @@ HciDevice::HciDevice(std::shared_ptr<HciTransport> transport,
}));
RegisterEventChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
- transport_->SendEvent(*packet);
+ transport_->Send(PacketType::EVENT, *packet);
});
RegisterAclChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
- transport_->SendAcl(*packet);
+ transport_->Send(PacketType::ACL, *packet);
});
RegisterScoChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
- transport_->SendSco(*packet);
+ transport_->Send(PacketType::SCO, *packet);
});
RegisterIsoChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
- transport_->SendIso(*packet);
+ transport_->Send(PacketType::ISO, *packet);
});
transport_->RegisterCallbacks(
- [this](const std::shared_ptr<std::vector<uint8_t>> command) {
- HandleCommand(command);
- },
- [this](const std::shared_ptr<std::vector<uint8_t>> acl) {
- HandleAcl(acl);
- },
- [this](const std::shared_ptr<std::vector<uint8_t>> sco) {
- HandleSco(sco);
- },
- [this](const std::shared_ptr<std::vector<uint8_t>> iso) {
- HandleIso(iso);
+ [this](PacketType packet_type,
+ const std::shared_ptr<std::vector<uint8_t>> packet) {
+ switch (packet_type) {
+ case PacketType::COMMAND:
+ HandleCommand(packet);
+ break;
+ case PacketType::ACL:
+ HandleAcl(packet);
+ break;
+ case PacketType::SCO:
+ HandleSco(packet);
+ break;
+ case PacketType::ISO:
+ HandleIso(packet);
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
},
[this]() {
INFO(id_, "HCI transport closed");
diff --git a/tools/rootcanal/model/hci/hci_sniffer.cc b/tools/rootcanal/model/hci/hci_sniffer.cc
index f0dbc139f0..ea3e2cbeac 100644
--- a/tools/rootcanal/model/hci/hci_sniffer.cc
+++ b/tools/rootcanal/model/hci/hci_sniffer.cc
@@ -73,32 +73,14 @@ void HciSniffer::AppendRecord(PacketDirection packet_direction,
output_->flush();
}
-void HciSniffer::RegisterCallbacks(PacketCallback command_callback,
- PacketCallback acl_callback,
- PacketCallback sco_callback,
- PacketCallback iso_callback,
+void HciSniffer::RegisterCallbacks(PacketCallback packet_callback,
CloseCallback close_callback) {
transport_->RegisterCallbacks(
- [this,
- command_callback](const std::shared_ptr<std::vector<uint8_t>> command) {
- AppendRecord(PacketDirection::HOST_TO_CONTROLLER, PacketType::COMMAND,
- *command);
- command_callback(command);
- },
- [this, acl_callback](const std::shared_ptr<std::vector<uint8_t>> acl) {
- AppendRecord(PacketDirection::HOST_TO_CONTROLLER, PacketType::ACL,
- *acl);
- acl_callback(acl);
- },
- [this, sco_callback](const std::shared_ptr<std::vector<uint8_t>> sco) {
- AppendRecord(PacketDirection::HOST_TO_CONTROLLER, PacketType::SCO,
- *sco);
- sco_callback(sco);
- },
- [this, iso_callback](const std::shared_ptr<std::vector<uint8_t>> iso) {
- AppendRecord(PacketDirection::HOST_TO_CONTROLLER, PacketType::ISO,
- *iso);
- iso_callback(iso);
+ [this, packet_callback](
+ PacketType packet_type,
+ const std::shared_ptr<std::vector<uint8_t>> packet) {
+ AppendRecord(PacketDirection::HOST_TO_CONTROLLER, packet_type, *packet);
+ packet_callback(packet_type, packet);
},
close_callback);
}
@@ -112,23 +94,10 @@ void HciSniffer::Close() {
}
}
-void HciSniffer::SendEvent(const std::vector<uint8_t>& packet) {
- AppendRecord(PacketDirection::CONTROLLER_TO_HOST, PacketType::EVENT, packet);
- transport_->SendEvent(packet);
-}
-
-void HciSniffer::SendAcl(const std::vector<uint8_t>& packet) {
- AppendRecord(PacketDirection::CONTROLLER_TO_HOST, PacketType::ACL, packet);
- transport_->SendAcl(packet);
-}
-
-void HciSniffer::SendSco(const std::vector<uint8_t>& packet) {
- AppendRecord(PacketDirection::CONTROLLER_TO_HOST, PacketType::SCO, packet);
- transport_->SendSco(packet);
+void HciSniffer::Send(PacketType packet_type,
+ const std::vector<uint8_t>& packet) {
+ AppendRecord(PacketDirection::CONTROLLER_TO_HOST, packet_type, packet);
+ transport_->Send(packet_type, packet);
}
-void HciSniffer::SendIso(const std::vector<uint8_t>& packet) {
- AppendRecord(PacketDirection::CONTROLLER_TO_HOST, PacketType::ISO, packet);
- transport_->SendIso(packet);
-}
} // namespace rootcanal
diff --git a/tools/rootcanal/model/hci/hci_sniffer.h b/tools/rootcanal/model/hci/hci_sniffer.h
index 206414e2f1..5ad47fbe7b 100644
--- a/tools/rootcanal/model/hci/hci_sniffer.h
+++ b/tools/rootcanal/model/hci/hci_sniffer.h
@@ -52,22 +52,13 @@ class HciSniffer : public HciTransport {
void SetOutputStream(std::shared_ptr<std::ostream> outputStream);
void SetPcapFilter(std::shared_ptr<PcapFilter> filter);
- void SendEvent(const std::vector<uint8_t>& packet) override;
+ void Send(PacketType packet_type,
+ const std::vector<uint8_t>& packet) override;
- void SendAcl(const std::vector<uint8_t>& packet) override;
-
- void SendSco(const std::vector<uint8_t>& packet) override;
-
- void SendIso(const std::vector<uint8_t>& packet) override;
-
- void RegisterCallbacks(PacketCallback command_callback,
- PacketCallback acl_callback,
- PacketCallback sco_callback,
- PacketCallback iso_callback,
+ void RegisterCallbacks(PacketCallback packet_callback,
CloseCallback close_callback) override;
void Tick() override;
-
void Close() override;
private:
diff --git a/tools/rootcanal/model/hci/hci_socket_transport.cc b/tools/rootcanal/model/hci/hci_socket_transport.cc
index c018b0ef1a..82632e466d 100644
--- a/tools/rootcanal/model/hci/hci_socket_transport.cc
+++ b/tools/rootcanal/model/hci/hci_socket_transport.cc
@@ -23,44 +23,41 @@ namespace rootcanal {
HciSocketTransport::HciSocketTransport(std::shared_ptr<AsyncDataChannel> socket)
: socket_(socket) {}
-void HciSocketTransport::RegisterCallbacks(PacketCallback command_callback,
- PacketCallback acl_callback,
- PacketCallback sco_callback,
- PacketCallback iso_callback,
+void HciSocketTransport::RegisterCallbacks(PacketCallback packet_callback,
CloseCallback close_callback) {
// TODO: Avoid the copy here by using new buffer in H4DataChannel
h4_ = H4DataChannelPacketizer(
socket_,
- [command_callback](const std::vector<uint8_t>& raw_command) {
+ [packet_callback](const std::vector<uint8_t>& raw_command) {
std::shared_ptr<std::vector<uint8_t>> packet_copy =
std::make_shared<std::vector<uint8_t>>(raw_command);
- command_callback(packet_copy);
+ packet_callback(PacketType::COMMAND, packet_copy);
},
[](const std::vector<uint8_t>&) {
FATAL("Unexpected Event in HciSocketTransport!");
},
- [acl_callback](const std::vector<uint8_t>& raw_acl) {
+ [packet_callback](const std::vector<uint8_t>& raw_acl) {
std::shared_ptr<std::vector<uint8_t>> packet_copy =
std::make_shared<std::vector<uint8_t>>(raw_acl);
- acl_callback(packet_copy);
+ packet_callback(PacketType::ACL, packet_copy);
},
- [sco_callback](const std::vector<uint8_t>& raw_sco) {
+ [packet_callback](const std::vector<uint8_t>& raw_sco) {
std::shared_ptr<std::vector<uint8_t>> packet_copy =
std::make_shared<std::vector<uint8_t>>(raw_sco);
- sco_callback(packet_copy);
+ packet_callback(PacketType::SCO, packet_copy);
},
- [iso_callback](const std::vector<uint8_t>& raw_iso) {
+ [packet_callback](const std::vector<uint8_t>& raw_iso) {
std::shared_ptr<std::vector<uint8_t>> packet_copy =
std::make_shared<std::vector<uint8_t>>(raw_iso);
- iso_callback(packet_copy);
+ packet_callback(PacketType::ISO, packet_copy);
},
close_callback);
}
void HciSocketTransport::Tick() { h4_.OnDataReady(socket_); }
-void HciSocketTransport::SendHci(PacketType packet_type,
- const std::vector<uint8_t>& packet) {
+void HciSocketTransport::Send(PacketType packet_type,
+ const std::vector<uint8_t>& packet) {
if (!socket_ || !socket_->Connected()) {
INFO("Closed socket. Dropping packet of type {}", packet_type);
return;
@@ -69,22 +66,6 @@ void HciSocketTransport::SendHci(PacketType packet_type,
h4_.Send(type, packet.data(), packet.size());
}
-void HciSocketTransport::SendEvent(const std::vector<uint8_t>& packet) {
- SendHci(PacketType::EVENT, packet);
-}
-
-void HciSocketTransport::SendAcl(const std::vector<uint8_t>& packet) {
- SendHci(PacketType::ACL, packet);
-}
-
-void HciSocketTransport::SendSco(const std::vector<uint8_t>& packet) {
- SendHci(PacketType::SCO, packet);
-}
-
-void HciSocketTransport::SendIso(const std::vector<uint8_t>& packet) {
- SendHci(PacketType::ISO, packet);
-}
-
void HciSocketTransport::Close() { socket_->Close(); }
} // namespace rootcanal
diff --git a/tools/rootcanal/model/hci/hci_socket_transport.h b/tools/rootcanal/model/hci/hci_socket_transport.h
index 6bd2d8e7e5..e6e4a356ac 100644
--- a/tools/rootcanal/model/hci/hci_socket_transport.h
+++ b/tools/rootcanal/model/hci/hci_socket_transport.h
@@ -36,27 +36,16 @@ class HciSocketTransport : public HciTransport {
return std::make_shared<HciSocketTransport>(socket);
}
- void SendEvent(const std::vector<uint8_t>& packet) override;
+ void Send(PacketType packet_type,
+ const std::vector<uint8_t>& packet) override;
- void SendAcl(const std::vector<uint8_t>& packet) override;
-
- void SendSco(const std::vector<uint8_t>& packet) override;
-
- void SendIso(const std::vector<uint8_t>& packet) override;
-
- void RegisterCallbacks(PacketCallback command_callback,
- PacketCallback acl_callback,
- PacketCallback sco_callback,
- PacketCallback iso_callback,
+ void RegisterCallbacks(PacketCallback packet_callback,
CloseCallback close_callback) override;
void Tick() override;
-
void Close() override;
private:
- void SendHci(PacketType packet_type, const std::vector<uint8_t>& packet);
-
std::shared_ptr<AsyncDataChannel> socket_;
H4DataChannelPacketizer h4_{socket_,
[](const std::vector<uint8_t>&) {},
diff --git a/tools/rootcanal/model/hci/hci_transport.h b/tools/rootcanal/model/hci/hci_transport.h
index e682801255..5aa10f160c 100644
--- a/tools/rootcanal/model/hci/hci_transport.h
+++ b/tools/rootcanal/model/hci/hci_transport.h
@@ -20,32 +20,28 @@
#include <memory>
#include <vector>
+#include "model/hci/h4.h"
+
namespace rootcanal {
-using PacketCallback =
- std::function<void(const std::shared_ptr<std::vector<uint8_t>>)>;
+using PacketCallback = std::function<void(
+ PacketType, const std::shared_ptr<std::vector<uint8_t>>)>;
using CloseCallback = std::function<void()>;
class HciTransport {
public:
virtual ~HciTransport() = default;
- virtual void SendEvent(const std::vector<uint8_t>& packet) = 0;
-
- virtual void SendAcl(const std::vector<uint8_t>& packet) = 0;
-
- virtual void SendSco(const std::vector<uint8_t>& packet) = 0;
+ /// Send the input HCI packet with the selected H4 packet type.
+ /// The packet data contains the H4 header but not the IDC byte.
+ virtual void Send(PacketType packet_type,
+ std::vector<uint8_t> const& packet) = 0;
- virtual void SendIso(const std::vector<uint8_t>& packet) = 0;
-
- virtual void RegisterCallbacks(PacketCallback command_callback,
- PacketCallback acl_callback,
- PacketCallback sco_callback,
- PacketCallback iso_callback,
+ /// Register the handler for received HCI packets.
+ virtual void RegisterCallbacks(PacketCallback packet_callback,
CloseCallback close_callback) = 0;
virtual void Tick() = 0;
-
virtual void Close() = 0;
};
diff --git a/tools/rootcanal/packets/hci/hci_packets.pdl b/tools/rootcanal/packets/hci_packets.pdl
index 0743244999..a99774499b 100644
--- a/tools/rootcanal/packets/hci/hci_packets.pdl
+++ b/tools/rootcanal/packets/hci_packets.pdl
@@ -3279,12 +3279,12 @@ packet LeCreateConnection : Command (op_code = LE_CREATE_CONNECTION) {
peer_address_type : AddressType,
peer_address : Address,
own_address_type : OwnAddressType,
- conn_interval_min : 16, // 0x0006-0x0C80 (7.5ms to 4s)
- conn_interval_max : 16, // 0x0006-0x0C80 (7.5ms to 4s)
- conn_latency : 16, // 0x0006-0x01F3
+ connection_interval_min : 16, // 0x0006-0x0C80 (7.5ms to 4s)
+ connection_interval_max : 16, // 0x0006-0x0C80 (7.5ms to 4s)
+ max_latency : 16, // 0x0006-0x01F3
supervision_timeout : 16, // 0x00A to 0x0C80 (100ms to 32s)
- minimum_ce_length : 16, // 0.625ms
- maximum_ce_length : 16, // 0.625ms
+ min_ce_length : 16, // 0.625ms
+ max_ce_length : 16, // 0.625ms
}
packet LeCreateConnectionStatus : CommandStatus (command_op_code = LE_CREATE_CONNECTION) {
@@ -3347,12 +3347,12 @@ packet LeRemoveDeviceFromFilterAcceptListComplete : CommandComplete (command_op_
packet LeConnectionUpdate : Command (op_code = LE_CONNECTION_UPDATE) {
connection_handle : 12,
_reserved_ : 4,
- conn_interval_min : 16, // 0x0006-0x0C80 (7.5ms to 4s)
- conn_interval_max : 16, // 0x0006-0x0C80 (7.5ms to 4s)
- conn_latency : 16, // 0x0006-0x01F3
+ connection_interval_min : 16, // 0x0006-0x0C80 (7.5ms to 4s)
+ connection_interval_max : 16, // 0x0006-0x0C80 (7.5ms to 4s)
+ max_latency : 16, // 0x0006-0x01F3
supervision_timeout : 16, // 0x00A to 0x0C80 (100ms to 32s)
- minimum_ce_length : 16, // 0.625ms
- maximum_ce_length : 16, // 0.625ms
+ min_ce_length : 16, // 0.625ms
+ max_ce_length : 16, // 0.625ms
}
packet LeConnectionUpdateStatus : CommandStatus (command_op_code = LE_CONNECTION_UPDATE) {
@@ -3988,7 +3988,7 @@ packet LeSetPeriodicAdvertisingEnableComplete : CommandComplete (command_op_code
status : ErrorCode,
}
-struct PhyScanParameters {
+struct ScanningPhyParameters {
le_scan_type : LeScanType,
le_scan_interval : 16, // 0x0004-0xFFFF Default 0x10 (10ms)
le_scan_window : 16, // 0x004-0xFFFF Default 0x10 (10ms)
@@ -3998,7 +3998,7 @@ packet LeSetExtendedScanParameters : Command (op_code = LE_SET_EXTENDED_SCAN_PAR
own_address_type : OwnAddressType,
scanning_filter_policy : LeScanningFilterPolicy,
scanning_phys : 8,
- parameters : PhyScanParameters[],
+ scanning_phy_parameters : ScanningPhyParameters[],
}
test LeSetExtendedScanParameters {
@@ -4040,12 +4040,12 @@ test LeSetExtendedScanEnableComplete {
"\x0e\x04\x01\x42\x20\x00",
}
-struct LeCreateConnPhyScanParameters {
+struct InitiatingPhyParameters {
scan_interval : 16, // 0x0004-0xFFFF
scan_window : 16, // < = LeScanInterval
- conn_interval_min : 16, // 0x0006-0x0C80 (7.5ms to 4s)
- conn_interval_max : 16, // 0x0006-0x0C80 (7.5ms to 4s)
- conn_latency : 16, // 0x0006-0x01F3
+ connection_interval_min : 16, // 0x0006-0x0C80 (7.5ms to 4s)
+ connection_interval_max : 16, // 0x0006-0x0C80 (7.5ms to 4s)
+ max_latency : 16, // 0x0006-0x01F3
supervision_timeout : 16, // 0x00A to 0x0C80 (100ms to 32s)
min_ce_length : 16, // 0.625ms
max_ce_length : 16, // 0.625ms
@@ -4054,10 +4054,10 @@ struct LeCreateConnPhyScanParameters {
packet LeExtendedCreateConnection : Command (op_code = LE_EXTENDED_CREATE_CONNECTION) {
initiator_filter_policy : InitiatorFilterPolicy,
own_address_type : OwnAddressType,
- peer_address_type : AddressType,
+ peer_address_type : PeerAddressType,
peer_address : Address,
initiating_phys : 8,
- phy_scan_parameters : LeCreateConnPhyScanParameters[],
+ initiating_phy_parameters : InitiatingPhyParameters[],
}
test LeExtendedCreateConnection {
@@ -5625,8 +5625,8 @@ packet LeConnectionComplete : LeMetaEvent (subevent_code = CONNECTION_COMPLETE)
role : Role,
peer_address_type : AddressType,
peer_address : Address,
- conn_interval : 16, // 0x006 - 0x0C80 (7.5ms - 4000ms)
- conn_latency : 16, // Number of connection events
+ connection_interval : 16, // 0x006 - 0x0C80 (7.5ms - 4000ms)
+ peripheral_latency : 16,
supervision_timeout : 16, // 0x000A to 0x0C80 (100ms to 32s)
central_clock_accuracy : ClockAccuracy,
}
@@ -5657,8 +5657,8 @@ packet LeConnectionUpdateComplete : LeMetaEvent (subevent_code = CONNECTION_UPDA
status : ErrorCode,
connection_handle : 12,
_reserved_ : 4,
- conn_interval : 16, // 0x006 - 0x0C80 (7.5ms - 4000ms)
- conn_latency : 16, // Number of connection events
+ connection_interval : 16, // 0x006 - 0x0C80 (7.5ms - 4000ms)
+ peripheral_latency : 16, // Number of connection events
supervision_timeout : 16, // 0x000A to 0x0C80 (100ms to 32s)
}
@@ -5713,8 +5713,8 @@ packet LeEnhancedConnectionComplete : LeMetaEvent (subevent_code = ENHANCED_CONN
peer_address : Address,
local_resolvable_private_address : Address,
peer_resolvable_private_address : Address,
- conn_interval : 16, // 0x006 - 0x0C80 (7.5ms - 4000ms)
- conn_latency : 16, // Number of connection events
+ connection_interval : 16, // 0x006 - 0x0C80 (7.5ms - 4000ms)
+ peripheral_latency : 16,
supervision_timeout : 16, // 0x000A to 0x0C80 (100ms to 32s)
central_clock_accuracy : ClockAccuracy,
}
diff --git a/tools/rootcanal/py/controller.py b/tools/rootcanal/py/controller.py
index 9c3e2a85fd..b4bbecaac0 100644
--- a/tools/rootcanal/py/controller.py
+++ b/tools/rootcanal/py/controller.py
@@ -373,13 +373,13 @@ class ControllerTest(unittest.IsolatedAsyncioTestCase):
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
peer_address=peer_address,
initiating_phys=0x1,
- phy_scan_parameters=[
- hci.LeCreateConnPhyScanParameters(
+ initiating_phy_parameters=[
+ hci.InitiatingPhyParameters(
scan_interval=0x200,
scan_window=0x100,
- conn_interval_min=0x200,
- conn_interval_max=0x200,
- conn_latency=0x6,
+ connection_interval_min=0x200,
+ connection_interval_max=0x200,
+ max_latency=0x6,
supervision_timeout=0xc80,
min_ce_length=0,
max_ce_length=0,
@@ -418,8 +418,8 @@ class ControllerTest(unittest.IsolatedAsyncioTestCase):
role=hci.Role.CENTRAL,
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
peer_address=peer_address,
- conn_interval=0x200,
- conn_latency=0x6,
+ connection_interval=0x200,
+ peripheral_latency=0x6,
supervision_timeout=0xc80,
central_clock_accuracy=hci.ClockAccuracy.PPM_500))
@@ -470,8 +470,8 @@ class ControllerTest(unittest.IsolatedAsyncioTestCase):
role=hci.Role.PERIPHERAL,
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
peer_address=peer_address,
- conn_interval=0x200,
- conn_latency=0x200,
+ connection_interval=0x200,
+ peripheral_latency=0x200,
supervision_timeout=0x200,
central_clock_accuracy=hci.ClockAccuracy.PPM_500))
diff --git a/tools/rootcanal/rust/CMakeLists.txt b/tools/rootcanal/rust/CMakeLists.txt
index 48751eacff..2e7c7cbaa9 100644
--- a/tools/rootcanal/rust/CMakeLists.txt
+++ b/tools/rootcanal/rust/CMakeLists.txt
@@ -2,7 +2,7 @@ message(STATUS "Enabling bluetooth LMP module.")
pdl_gen(
NAME hci_packets_rs
- INPUT ${ROOTCANAL_ROOT}/packets/hci/hci_packets.pdl
+ INPUT ${ROOTCANAL_ROOT}/packets/hci_packets.pdl
OUTPUT hci_packets.rs
LANG rust)
diff --git a/tools/rootcanal/rust/build.rs b/tools/rootcanal/rust/build.rs
index cd927f6ee2..793e1f93e1 100644
--- a/tools/rootcanal/rust/build.rs
+++ b/tools/rootcanal/rust/build.rs
@@ -31,7 +31,7 @@ fn main() {
install_generated_module(
"hci_packets.rs",
"HCI_PACKETS_PREBUILT",
- &PathBuf::from("../packets/hci/hci_packets.pdl").canonicalize().unwrap(),
+ &PathBuf::from("../packets/hci_packets.pdl").canonicalize().unwrap(),
);
}
@@ -60,8 +60,8 @@ fn generate_module(in_file: &PathBuf) {
// Find the pdl tool. Expecting it at CARGO_HOME/bin
let pdl = match env::var("CARGO_HOME") {
- Ok(dir) => PathBuf::from(dir).join("bin").join("pdl"),
- Err(_) => PathBuf::from("pdl"),
+ Ok(dir) => PathBuf::from(dir).join("bin").join("pdlc"),
+ Err(_) => PathBuf::from("pdlc"),
};
if !Path::new(pdl.as_os_str()).exists() {
diff --git a/tools/rootcanal/rust/src/lmp/procedure/secure_simple_pairing.rs b/tools/rootcanal/rust/src/lmp/procedure/secure_simple_pairing.rs
index 0c3c4e31a8..543219691f 100644
--- a/tools/rootcanal/rust/src/lmp/procedure/secure_simple_pairing.rs
+++ b/tools/rootcanal/rust/src/lmp/procedure/secure_simple_pairing.rs
@@ -143,11 +143,14 @@ async fn receive_public_key(ctx: &impl Context, transaction_id: u8) -> PublicKey
const COMMITMENT_VALUE_SIZE: usize = 16;
const NONCE_SIZE: usize = 16;
-async fn receive_commitment(ctx: &impl Context, skip_first: bool) {
- let commitment_value = [0; COMMITMENT_VALUE_SIZE];
+fn build_commitment(_ctx: &impl Context) -> [u8; COMMITMENT_VALUE_SIZE] {
+ [0; COMMITMENT_VALUE_SIZE]
+}
+
+async fn receive_commitment(ctx: &impl Context, confirm: Option<lmp::SimplePairingConfirm>) {
+ let commitment_value = build_commitment(ctx);
- if !skip_first {
- let confirm = ctx.receive_lmp_packet::<lmp::SimplePairingConfirm>().await;
+ if let Some(confirm) = confirm {
if confirm.get_commitment_value() != &commitment_value {
todo!();
}
@@ -177,16 +180,8 @@ async fn receive_commitment(ctx: &impl Context, skip_first: bool) {
.await;
}
-async fn send_commitment(ctx: &impl Context, skip_first: bool) {
- let commitment_value = [0; COMMITMENT_VALUE_SIZE];
-
- if !skip_first {
- ctx.send_lmp_packet(
- lmp::SimplePairingConfirmBuilder { transaction_id: 0, commitment_value }.build(),
- );
- }
-
- let confirm = ctx.receive_lmp_packet::<lmp::SimplePairingConfirm>().await;
+async fn send_commitment(ctx: &impl Context, confirm: lmp::SimplePairingConfirm) {
+ let commitment_value = build_commitment(ctx);
if confirm.get_commitment_value() != &commitment_value {
todo!();
@@ -437,14 +432,33 @@ pub async fn initiate(ctx: &impl Context) -> Result<(), ()> {
match auth_method {
AuthenticationMethod::NumericComparisonJustWork
| AuthenticationMethod::NumericComparisonUserConfirm => {
- send_commitment(ctx, true).await;
+ let confirm = ctx.receive_lmp_packet::<lmp::SimplePairingConfirm>().await;
+ send_commitment(ctx, confirm).await;
- user_confirmation_request(ctx).await?;
+ if user_confirmation_request(ctx).await.is_err() {
+ ctx.send_lmp_packet(
+ lmp::NumericComparisonFailedBuilder { transaction_id: 0 }.build(),
+ );
+ Err(())?;
+ }
Ok(())
}
AuthenticationMethod::PasskeyEntry => {
- if initiator.io_capability == hci::IoCapability::KeyboardOnly {
- user_passkey_request(ctx).await?;
+ let confirm = if initiator.io_capability == hci::IoCapability::KeyboardOnly {
+ if user_passkey_request(ctx).await.is_err() {
+ ctx.send_lmp_packet(
+ lmp::PasskeyFailedBuilder { transaction_id: 0 }.build(),
+ );
+ Err(())?;
+ }
+ ctx.send_lmp_packet(
+ lmp::SimplePairingConfirmBuilder {
+ transaction_id: 0,
+ commitment_value: build_commitment(ctx),
+ }
+ .build(),
+ );
+ ctx.receive_lmp_packet::<lmp::SimplePairingConfirm>().await
} else {
ctx.send_hci_event(
hci::UserPasskeyNotificationBuilder {
@@ -453,9 +467,32 @@ pub async fn initiate(ctx: &impl Context) -> Result<(), ()> {
}
.build(),
);
- }
- for _ in 0..PASSKEY_ENTRY_REPEAT_NUMBER {
- send_commitment(ctx, false).await;
+ ctx.send_lmp_packet(
+ lmp::SimplePairingConfirmBuilder {
+ transaction_id: 0,
+ commitment_value: build_commitment(ctx),
+ }
+ .build(),
+ );
+ match ctx
+ .receive_lmp_packet::<Either<lmp::SimplePairingConfirm, lmp::NotAccepted>>()
+ .await
+ {
+ Either::Left(confirm) => confirm,
+ Either::Right(_) => Err(())?,
+ }
+ };
+ send_commitment(ctx, confirm).await;
+ for _ in 1..PASSKEY_ENTRY_REPEAT_NUMBER {
+ ctx.send_lmp_packet(
+ lmp::SimplePairingConfirmBuilder {
+ transaction_id: 0,
+ commitment_value: build_commitment(ctx),
+ }
+ .build(),
+ );
+ let confirm = ctx.receive_lmp_packet::<lmp::SimplePairingConfirm>().await;
+ send_commitment(ctx, confirm).await;
}
Ok(())
}
@@ -464,7 +501,15 @@ pub async fn initiate(ctx: &impl Context) -> Result<(), ()> {
remote_oob_data_request(ctx).await?;
}
- send_commitment(ctx, false).await;
+ ctx.send_lmp_packet(
+ lmp::SimplePairingConfirmBuilder {
+ transaction_id: 0,
+ commitment_value: build_commitment(ctx),
+ }
+ .build(),
+ );
+ let confirm = ctx.receive_lmp_packet::<lmp::SimplePairingConfirm>().await;
+ send_commitment(ctx, confirm).await;
Ok(())
}
}
@@ -472,7 +517,6 @@ pub async fn initiate(ctx: &impl Context) -> Result<(), ()> {
.await;
if result.is_err() {
- ctx.send_lmp_packet(lmp::NumericComparisonFailedBuilder { transaction_id: 0 }.build());
ctx.send_hci_event(
hci::SimplePairingCompleteBuilder {
status: hci::ErrorCode::AuthenticationFailure,
@@ -644,37 +688,78 @@ pub async fn respond(ctx: &impl Context, request: lmp::IoCapabilityReq) -> Resul
// Authentication Stage 1
let auth_method = authentication_method(initiator, responder);
- let negative_user_confirmation = match auth_method {
- AuthenticationMethod::NumericComparisonJustWork
- | AuthenticationMethod::NumericComparisonUserConfirm => {
- receive_commitment(ctx, true).await;
+ let result: Result<bool, ()> = async {
+ match auth_method {
+ AuthenticationMethod::NumericComparisonJustWork
+ | AuthenticationMethod::NumericComparisonUserConfirm => {
+ receive_commitment(ctx, None).await;
- let user_confirmation = user_confirmation_request(ctx).await;
- user_confirmation.is_err()
- }
- AuthenticationMethod::PasskeyEntry => {
- if responder.io_capability == hci::IoCapability::KeyboardOnly {
- // TODO: handle error
- let _user_passkey = user_passkey_request(ctx).await;
- } else {
- ctx.send_hci_event(
- hci::UserPasskeyNotificationBuilder { bd_addr: ctx.peer_address(), passkey: 0 }
+ let user_confirmation = user_confirmation_request(ctx).await;
+ Ok(user_confirmation.is_err())
+ }
+ AuthenticationMethod::PasskeyEntry => {
+ let confirm = if responder.io_capability == hci::IoCapability::KeyboardOnly {
+ let user_passkey = user_passkey_request(ctx).await;
+ let confirm = ctx.receive_lmp_packet::<lmp::SimplePairingConfirm>().await;
+ if user_passkey.is_err() {
+ ctx.send_lmp_packet(
+ lmp::NotAcceptedBuilder {
+ transaction_id: 0,
+ not_accepted_opcode: lmp::Opcode::SimplePairingConfirm,
+ error_code: hci::ErrorCode::AuthenticationFailure.into(),
+ }.build(),
+ );
+ return Err(());
+ }
+ confirm
+ } else {
+ ctx.send_hci_event(
+ hci::UserPasskeyNotificationBuilder {
+ bd_addr: ctx.peer_address(),
+ passkey: 0,
+ }
.build(),
- );
+ );
+ match ctx
+ .receive_lmp_packet::<Either<lmp::SimplePairingConfirm, lmp::PasskeyFailed>>()
+ .await
+ {
+ Either::Left(confirm) => confirm,
+ Either::Right(_) => Err(())?,
+ }
+ };
+ receive_commitment(ctx, Some(confirm)).await;
+ for _ in 1..PASSKEY_ENTRY_REPEAT_NUMBER {
+ let confirm = ctx.receive_lmp_packet::<lmp::SimplePairingConfirm>().await;
+ receive_commitment(ctx, Some(confirm)).await;
+ }
+ Ok(false)
}
- for _ in 0..PASSKEY_ENTRY_REPEAT_NUMBER {
- receive_commitment(ctx, false).await;
+ AuthenticationMethod::OutOfBand => {
+ if responder.oob_data_present != hci::OobDataPresent::NotPresent {
+ // TODO: handle error
+ let _remote_oob_data = remote_oob_data_request(ctx).await;
+ }
+
+ let confirm = ctx.receive_lmp_packet::<lmp::SimplePairingConfirm>().await;
+ receive_commitment(ctx, Some(confirm)).await;
+ Ok(false)
}
- false
}
- AuthenticationMethod::OutOfBand => {
- if responder.oob_data_present != hci::OobDataPresent::NotPresent {
- // TODO: handle error
- let _remote_oob_data = remote_oob_data_request(ctx).await;
- }
+ }
+ .await;
- receive_commitment(ctx, false).await;
- false
+ let negative_user_confirmation = match result {
+ Ok(negative_user_confirmation) => negative_user_confirmation,
+ Err(_) => {
+ ctx.send_hci_event(
+ hci::SimplePairingCompleteBuilder {
+ status: hci::ErrorCode::AuthenticationFailure,
+ bd_addr: ctx.peer_address(),
+ }
+ .build(),
+ );
+ return Err(());
}
};
@@ -867,8 +952,7 @@ mod tests {
}
#[test]
- #[should_panic] // TODO: make the test pass
- fn passkey_entry_initiator_failure_on_initiating_side() {
+ fn passkey_entry_initiator_negative_reply_on_initiating_side() {
let context = TestContext::new();
let procedure = initiate;
@@ -876,8 +960,15 @@ mod tests {
}
#[test]
- #[should_panic] // TODO: make the test pass
- fn passkey_entry_responder_failure_on_initiating_side() {
+ fn passkey_entry_responder_negative_reply_on_responding_side() {
+ let context = TestContext::new();
+ let procedure = respond;
+
+ include!("../../../test/SP/BV-14bis-C.in");
+ }
+
+ #[test]
+ fn passkey_entry_responder_negative_reply_on_initiating_side() {
let context = TestContext::new();
let procedure = respond;
@@ -885,6 +976,14 @@ mod tests {
}
#[test]
+ fn passkey_entry_initiator_negative_reply_on_responding_side() {
+ let context = TestContext::new();
+ let procedure = initiate;
+
+ include!("../../../test/SP/BV-15bis-C.in");
+ }
+
+ #[test]
#[should_panic] // TODO: make the test pass
fn passkey_entry_initiator_failure_on_responding_side() {
let context = TestContext::new();
diff --git a/tools/rootcanal/rust/test/SP/BV-14bis-C.in b/tools/rootcanal/rust/test/SP/BV-14bis-C.in
new file mode 100644
index 0000000000..b98f45096d
--- /dev/null
+++ b/tools/rootcanal/rust/test/SP/BV-14bis-C.in
@@ -0,0 +1,106 @@
+// Passkey entry responder, negative reply on responding side:
+// - Test case not present in LMP.TS, but other permutations are described in SP/BV-14-C, SP/BV-15-C
+// - IUT is KeyboardOnly, responder
+// - Lower Tester is Display, initiator
+// - IUT fails passkey entry with User_Passkey_Request_NegativeReply, responds Not Accepted to the SimplePairingConfirm
+sequence! { procedure, context,
+ // ACL Connection Established
+ Lower Tester -> IUT: IoCapabilityReq {
+ transaction_id: 0,
+ io_capabilities: 0x00,
+ oob_authentication_data: 0x00,
+ authentication_requirement: 0x01,
+ }
+ IUT -> Upper Tester: IoCapabilityResponse {
+ bd_addr: context.peer_address(),
+ io_capability: IoCapability::DisplayOnly,
+ oob_data_present: OobDataPresent::NotPresent,
+ authentication_requirements: AuthenticationRequirements::NoBondingMitmProtection,
+ }
+ IUT -> Upper Tester: IoCapabilityRequest {
+ bd_addr: context.peer_address(),
+ }
+ Upper Tester -> IUT: IoCapabilityRequestReply {
+ bd_addr: context.peer_address(),
+ io_capability: IoCapability::KeyboardOnly,
+ oob_present: OobDataPresent::NotPresent,
+ authentication_requirements: AuthenticationRequirements::NoBondingMitmProtection,
+ }
+ IUT -> Upper Tester: IoCapabilityRequestReplyComplete {
+ num_hci_command_packets: 1,
+ status: ErrorCode::Success,
+ bd_addr: context.peer_address(),
+ }
+ IUT -> Lower Tester: IoCapabilityRes {
+ transaction_id: 0,
+ io_capabilities: 0x02,
+ oob_authentication_data: 0x00,
+ authentication_requirement: 0x01,
+ }
+ // Public Key Exchange
+ Lower Tester -> IUT: EncapsulatedHeader {
+ transaction_id: 0,
+ major_type: 1,
+ minor_type: 1,
+ payload_length: 48,
+ }
+ IUT -> Lower Tester: Accepted {
+ transaction_id: 0,
+ accepted_opcode: Opcode::EncapsulatedHeader,
+ }
+ repeat 3 times with (part in peer_p192_public_key()) {
+ Lower Tester -> IUT: EncapsulatedPayload {
+ transaction_id: 0,
+ data: part,
+ }
+ IUT -> Lower Tester: Accepted {
+ transaction_id: 0,
+ accepted_opcode: Opcode::EncapsulatedPayload,
+ }
+ }
+ IUT -> Lower Tester: EncapsulatedHeader {
+ transaction_id: 0,
+ major_type: 1,
+ minor_type: 1,
+ payload_length: 48,
+ }
+ Lower Tester -> IUT: Accepted {
+ transaction_id: 0,
+ accepted_opcode: Opcode::EncapsulatedHeader,
+ }
+ repeat 3 times with (part in local_p192_public_key(&context)) {
+ IUT -> Lower Tester: EncapsulatedPayload {
+ transaction_id: 0,
+ data: part,
+ }
+ Lower Tester -> IUT: Accepted {
+ transaction_id: 0,
+ accepted_opcode: Opcode::EncapsulatedPayload,
+ }
+ }
+ // Authentication Stage 1: Passkey Entry Protocol
+ IUT -> Upper Tester: UserPasskeyRequest {
+ bd_addr: context.peer_address(),
+ }
+ Upper Tester -> IUT: UserPasskeyRequestNegativeReply {
+ bd_addr: context.peer_address(),
+ }
+ IUT -> Upper Tester: UserPasskeyRequestNegativeReplyComplete {
+ num_hci_command_packets: 1,
+ status: ErrorCode::Success,
+ bd_addr: context.peer_address(),
+ }
+ Lower Tester -> IUT: SimplePairingConfirm {
+ transaction_id: 0,
+ commitment_value: [0; 16],
+ }
+ IUT -> Lower Tester: NotAccepted {
+ transaction_id: 0,
+ not_accepted_opcode: Opcode::SimplePairingConfirm,
+ error_code: ErrorCode::AuthenticationFailure.into(),
+ }
+ IUT -> Upper Tester: SimplePairingComplete {
+ status: ErrorCode::AuthenticationFailure,
+ bd_addr: context.peer_address(),
+ }
+}
diff --git a/tools/rootcanal/rust/test/SP/BV-15bis-C.in b/tools/rootcanal/rust/test/SP/BV-15bis-C.in
new file mode 100644
index 0000000000..f9fda299c8
--- /dev/null
+++ b/tools/rootcanal/rust/test/SP/BV-15bis-C.in
@@ -0,0 +1,118 @@
+// Passkey entry initiator, negative reply on responding side:
+// - Test case not present in LMP.TS, but other permutations are described in SP/BV-14-C, SP/BV-15-C
+// - IUT is DisplayOnly, initiator
+// - Lower Tester is KeyboardOnly, responder
+// - Lower Tester fails passkey entry with User_Passkey_Request_NegativeReply, responds Not Accepted to the SimplePairingConfirm
+sequence! { procedure, context,
+ // ACL Connection Established
+ Upper Tester -> IUT: AuthenticationRequested {
+ connection_handle: context.peer_handle()
+ }
+ IUT -> Upper Tester: AuthenticationRequestedStatus {
+ num_hci_command_packets: 1,
+ status: ErrorCode::Success,
+ }
+ IUT -> Upper Tester: LinkKeyRequest {
+ bd_addr: context.peer_address(),
+ }
+ Upper Tester -> IUT: LinkKeyRequestNegativeReply {
+ bd_addr: context.peer_address(),
+ }
+ IUT -> Upper Tester: LinkKeyRequestNegativeReplyComplete {
+ num_hci_command_packets: 1,
+ status: ErrorCode::Success,
+ bd_addr: context.peer_address(),
+ }
+ IUT -> Upper Tester: IoCapabilityRequest {
+ bd_addr: context.peer_address(),
+ }
+ Upper Tester -> IUT: IoCapabilityRequestReply {
+ bd_addr: context.peer_address(),
+ io_capability: IoCapability::DisplayOnly,
+ oob_present: OobDataPresent::NotPresent,
+ authentication_requirements: AuthenticationRequirements::NoBondingMitmProtection,
+ }
+ IUT -> Upper Tester: IoCapabilityRequestReplyComplete {
+ num_hci_command_packets: 1,
+ status: ErrorCode::Success,
+ bd_addr: context.peer_address(),
+ }
+ IUT -> Lower Tester: IoCapabilityReq {
+ transaction_id: 0,
+ io_capabilities: 0x00,
+ oob_authentication_data: 0x00,
+ authentication_requirement: 0x01,
+ }
+ Lower Tester -> IUT: IoCapabilityRes {
+ transaction_id: 0,
+ io_capabilities: 0x02,
+ oob_authentication_data: 0x00,
+ authentication_requirement: 0x01,
+ }
+ IUT -> Upper Tester: IoCapabilityResponse {
+ bd_addr: context.peer_address(),
+ io_capability: IoCapability::KeyboardOnly,
+ oob_data_present: OobDataPresent::NotPresent,
+ authentication_requirements: AuthenticationRequirements::NoBondingMitmProtection,
+ }
+ // Public Key Exchange
+ IUT -> Lower Tester: EncapsulatedHeader {
+ transaction_id: 0,
+ major_type: 1,
+ minor_type: 1,
+ payload_length: 48,
+ }
+ Lower Tester -> IUT: Accepted {
+ transaction_id: 0,
+ accepted_opcode: Opcode::EncapsulatedHeader,
+ }
+ repeat 3 times with (part in local_p192_public_key(&context)) {
+ IUT -> Lower Tester: EncapsulatedPayload {
+ transaction_id: 0,
+ data: part,
+ }
+ Lower Tester -> IUT: Accepted {
+ transaction_id: 0,
+ accepted_opcode: Opcode::EncapsulatedPayload,
+ }
+ }
+ Lower Tester -> IUT: EncapsulatedHeader {
+ transaction_id: 0,
+ major_type: 1,
+ minor_type: 1,
+ payload_length: 48,
+ }
+ IUT -> Lower Tester: Accepted {
+ transaction_id: 0,
+ accepted_opcode: Opcode::EncapsulatedHeader,
+ }
+ repeat 3 times with (part in peer_p192_public_key()) {
+ Lower Tester -> IUT: EncapsulatedPayload {
+ transaction_id: 0,
+ data: part,
+ }
+ IUT -> Lower Tester: Accepted {
+ transaction_id: 0,
+ accepted_opcode: Opcode::EncapsulatedPayload,
+ }
+ }
+ // Authentication Stage 1: Passkey Entry Protocol
+ IUT -> Upper Tester: UserPasskeyNotification { bd_addr: context.peer_address(), passkey: 0 }
+ IUT -> Lower Tester: SimplePairingConfirm {
+ transaction_id: 0,
+ commitment_value: [0; 16],
+ }
+ Lower Tester -> IUT: NotAccepted {
+ transaction_id: 0,
+ not_accepted_opcode: Opcode::SimplePairingConfirm,
+ error_code: ErrorCode::AuthenticationFailure.into(),
+ }
+ IUT -> Upper Tester: SimplePairingComplete {
+ status: ErrorCode::AuthenticationFailure,
+ bd_addr: context.peer_address(),
+ }
+ IUT -> Upper Tester: AuthenticationComplete {
+ status: ErrorCode::AuthenticationFailure,
+ connection_handle: context.peer_handle(),
+ }
+}
diff --git a/tools/rootcanal/test/LL/CON_/CEN/BV_41_C.py b/tools/rootcanal/test/LL/CON_/CEN/BV_41_C.py
index c3b719082e..9d377ef54a 100644
--- a/tools/rootcanal/test/LL/CON_/CEN/BV_41_C.py
+++ b/tools/rootcanal/test/LL/CON_/CEN/BV_41_C.py
@@ -46,13 +46,13 @@ class Test(ControllerTest):
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
peer_address=peer_address,
initiating_phys=0x1,
- phy_scan_parameters=[
- hci.LeCreateConnPhyScanParameters(
+ initiating_phy_parameters=[
+ hci.InitiatingPhyParameters(
scan_interval=0x200,
scan_window=0x100,
- conn_interval_min=0x200,
- conn_interval_max=0x200,
- conn_latency=0x6,
+ connection_interval_min=0x200,
+ connection_interval_max=0x200,
+ max_latency=0x6,
supervision_timeout=0xc80,
min_ce_length=0,
max_ce_length=0,
@@ -91,8 +91,8 @@ class Test(ControllerTest):
role=hci.Role.CENTRAL,
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
peer_address=peer_address,
- conn_interval=0x200,
- conn_latency=0x6,
+ connection_interval=0x200,
+ peripheral_latency=0x6,
supervision_timeout=0xc80,
central_clock_accuracy=hci.ClockAccuracy.PPM_500))
diff --git a/tools/rootcanal/test/LL/CON_/CEN/BV_43_C.py b/tools/rootcanal/test/LL/CON_/CEN/BV_43_C.py
index ec5b68ba4a..914df4cfe9 100644
--- a/tools/rootcanal/test/LL/CON_/CEN/BV_43_C.py
+++ b/tools/rootcanal/test/LL/CON_/CEN/BV_43_C.py
@@ -43,13 +43,13 @@ class Test(ControllerTest):
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
peer_address=peer_address,
initiating_phys=0x1,
- phy_scan_parameters=[
- hci.LeCreateConnPhyScanParameters(
+ initiating_phy_parameters=[
+ hci.InitiatingPhyParameters(
scan_interval=0x200,
scan_window=0x100,
- conn_interval_min=0x200,
- conn_interval_max=0x200,
- conn_latency=0x6,
+ connection_interval_min=0x200,
+ connection_interval_max=0x200,
+ max_latency=0x6,
supervision_timeout=0xc80,
min_ce_length=0,
max_ce_length=0,
@@ -88,8 +88,8 @@ class Test(ControllerTest):
role=hci.Role.CENTRAL,
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
peer_address=peer_address,
- conn_interval=0x200,
- conn_latency=0x6,
+ connection_interval=0x200,
+ peripheral_latency=0x6,
supervision_timeout=0xc80,
central_clock_accuracy=hci.ClockAccuracy.PPM_500))
diff --git a/tools/rootcanal/test/LL/CON_/PER/BV_40_C.py b/tools/rootcanal/test/LL/CON_/PER/BV_40_C.py
index 201beeb3cd..045bca32a3 100644
--- a/tools/rootcanal/test/LL/CON_/PER/BV_40_C.py
+++ b/tools/rootcanal/test/LL/CON_/PER/BV_40_C.py
@@ -77,8 +77,8 @@ class Test(ControllerTest):
role=hci.Role.PERIPHERAL,
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
peer_address=peer_address,
- conn_interval=0x200,
- conn_latency=0x200,
+ connection_interval=0x200,
+ peripheral_latency=0x200,
supervision_timeout=0x200,
central_clock_accuracy=hci.ClockAccuracy.PPM_500))
diff --git a/tools/rootcanal/test/LL/CON_/PER/BV_42_C.py b/tools/rootcanal/test/LL/CON_/PER/BV_42_C.py
index 4f19d701c5..ae067c2269 100644
--- a/tools/rootcanal/test/LL/CON_/PER/BV_42_C.py
+++ b/tools/rootcanal/test/LL/CON_/PER/BV_42_C.py
@@ -77,8 +77,8 @@ class Test(ControllerTest):
role=hci.Role.PERIPHERAL,
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
peer_address=peer_address,
- conn_interval=0x200,
- conn_latency=0x200,
+ connection_interval=0x200,
+ peripheral_latency=0x200,
supervision_timeout=0x200,
central_clock_accuracy=hci.ClockAccuracy.PPM_500))
diff --git a/tools/rootcanal/test/LL/DDI/ADV/BV_06_C.py b/tools/rootcanal/test/LL/DDI/ADV/BV_06_C.py
index f850c57143..f52edd3deb 100644
--- a/tools/rootcanal/test/LL/DDI/ADV/BV_06_C.py
+++ b/tools/rootcanal/test/LL/DDI/ADV/BV_06_C.py
@@ -95,8 +95,8 @@ class Test(ControllerTest):
role=hci.Role.PERIPHERAL,
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
peer_address=peer_address,
- conn_interval=LL_initiator_connInterval,
- conn_latency=LL_initiator_connPeripheralLatency,
+ connection_interval=LL_initiator_connInterval,
+ peripheral_latency=LL_initiator_connPeripheralLatency,
supervision_timeout=LL_initiator_connSupervisionTimeout,
central_clock_accuracy=hci.ClockAccuracy.PPM_500))
diff --git a/tools/rootcanal/test/LL/DDI/ADV/BV_07_C.py b/tools/rootcanal/test/LL/DDI/ADV/BV_07_C.py
index c4b10cdc8e..271a4fc564 100644
--- a/tools/rootcanal/test/LL/DDI/ADV/BV_07_C.py
+++ b/tools/rootcanal/test/LL/DDI/ADV/BV_07_C.py
@@ -125,8 +125,8 @@ class Test(ControllerTest):
role=hci.Role.PERIPHERAL,
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
peer_address=peer_address,
- conn_interval=LL_initiator_connInterval,
- conn_latency=LL_initiator_connPeripheralLatency,
+ connection_interval=LL_initiator_connInterval,
+ peripheral_latency=LL_initiator_connPeripheralLatency,
supervision_timeout=LL_initiator_connSupervisionTimeout,
central_clock_accuracy=hci.ClockAccuracy.PPM_500))
diff --git a/tools/rootcanal/test/LL/DDI/ADV/BV_09_C.py b/tools/rootcanal/test/LL/DDI/ADV/BV_09_C.py
index d583ef4cf3..719ddc76e3 100644
--- a/tools/rootcanal/test/LL/DDI/ADV/BV_09_C.py
+++ b/tools/rootcanal/test/LL/DDI/ADV/BV_09_C.py
@@ -310,8 +310,8 @@ class Test(ControllerTest):
peer_address_type=(hci.AddressType.PUBLIC_DEVICE_ADDRESS if peer_address_type == ll.AddressType.PUBLIC
else hci.AddressType.RANDOM_DEVICE_ADDRESS),
peer_address=peer_address,
- conn_interval=self.LL_initiator_connInterval,
- conn_latency=self.LL_initiator_connPeripheralLatency,
+ connection_interval=self.LL_initiator_connInterval,
+ peripheral_latency=self.LL_initiator_connPeripheralLatency,
supervision_timeout=self.LL_initiator_connSupervisionTimeout,
central_clock_accuracy=hci.ClockAccuracy.PPM_500))
@@ -380,8 +380,8 @@ class Test(ControllerTest):
peer_address_type=(hci.AddressType.PUBLIC_DEVICE_ADDRESS if peer_address_type == ll.AddressType.PUBLIC
else hci.AddressType.RANDOM_DEVICE_ADDRESS),
peer_address=peer_address,
- conn_interval=self.LL_initiator_connInterval,
- conn_latency=self.LL_initiator_connPeripheralLatency,
+ connection_interval=self.LL_initiator_connInterval,
+ peripheral_latency=self.LL_initiator_connPeripheralLatency,
supervision_timeout=self.LL_initiator_connSupervisionTimeout,
central_clock_accuracy=hci.ClockAccuracy.PPM_500))
diff --git a/tools/rootcanal/test/LL/DDI/ADV/BV_11_C.py b/tools/rootcanal/test/LL/DDI/ADV/BV_11_C.py
index 1b0953ac51..014417f9be 100644
--- a/tools/rootcanal/test/LL/DDI/ADV/BV_11_C.py
+++ b/tools/rootcanal/test/LL/DDI/ADV/BV_11_C.py
@@ -137,8 +137,8 @@ class Test(ControllerTest):
role=hci.Role.PERIPHERAL,
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
peer_address=peer_address,
- conn_interval=self.LL_initiator_connInterval,
- conn_latency=self.LL_initiator_connPeripheralLatency,
+ connection_interval=self.LL_initiator_connInterval,
+ peripheral_latency=self.LL_initiator_connPeripheralLatency,
supervision_timeout=self.LL_initiator_connSupervisionTimeout,
central_clock_accuracy=hci.ClockAccuracy.PPM_500))
diff --git a/tools/rootcanal/test/LL/DDI/ADV/BV_19_C.py b/tools/rootcanal/test/LL/DDI/ADV/BV_19_C.py
index ba996c7ad6..9247324a4f 100644
--- a/tools/rootcanal/test/LL/DDI/ADV/BV_19_C.py
+++ b/tools/rootcanal/test/LL/DDI/ADV/BV_19_C.py
@@ -112,8 +112,8 @@ class Test(ControllerTest):
role=hci.Role.PERIPHERAL,
peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
peer_address=public_peer_address,
- conn_interval=self.LL_initiator_connInterval,
- conn_latency=self.LL_initiator_connPeripheralLatency,
+ connection_interval=self.LL_initiator_connInterval,
+ peripheral_latency=self.LL_initiator_connPeripheralLatency,
supervision_timeout=self.LL_initiator_connSupervisionTimeout,
central_clock_accuracy=hci.ClockAccuracy.PPM_500))
diff --git a/tools/rootcanal/test/LL/DDI/SCN/BV_19_C.py b/tools/rootcanal/test/LL/DDI/SCN/BV_19_C.py
index 04bda10551..41c3db5b94 100644
--- a/tools/rootcanal/test/LL/DDI/SCN/BV_19_C.py
+++ b/tools/rootcanal/test/LL/DDI/SCN/BV_19_C.py
@@ -82,10 +82,10 @@ class Test(ControllerTest):
hci.LeSetExtendedScanParameters(own_address_type=hci.OwnAddressType.PUBLIC_DEVICE_ADDRESS,
scanning_filter_policy=hci.LeScanningFilterPolicy.ACCEPT_ALL,
scanning_phys=0x1,
- parameters=[
- hci.PhyScanParameters(le_scan_type=hci.LeScanType.PASSIVE,
- le_scan_interval=0x0010,
- le_scan_window=0x0010)
+ scanning_phy_parameters=[
+ hci.ScanningPhyParameters(le_scan_type=hci.LeScanType.PASSIVE,
+ le_scan_interval=0x0010,
+ le_scan_window=0x0010)
]))
await self.expect_evt(
diff --git a/tools/rootcanal/test/LL/DDI/SCN/BV_79_C.py b/tools/rootcanal/test/LL/DDI/SCN/BV_79_C.py
index a27b0a1058..80a6245c68 100644
--- a/tools/rootcanal/test/LL/DDI/SCN/BV_79_C.py
+++ b/tools/rootcanal/test/LL/DDI/SCN/BV_79_C.py
@@ -52,10 +52,10 @@ class Test(ControllerTest):
hci.LeSetExtendedScanParameters(own_address_type=hci.OwnAddressType.PUBLIC_DEVICE_ADDRESS,
scanning_filter_policy=hci.LeScanningFilterPolicy.ACCEPT_ALL,
scanning_phys=0x1,
- parameters=[
- hci.PhyScanParameters(le_scan_type=hci.LeScanType.PASSIVE,
- le_scan_interval=0x0010,
- le_scan_window=0x0010)
+ scanning_phy_parameters=[
+ hci.ScanningPhyParameters(le_scan_type=hci.LeScanType.PASSIVE,
+ le_scan_interval=0x0010,
+ le_scan_window=0x0010)
]))
await self.expect_evt(
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
diff --git a/tools/rootcanal/test/controller/le/le_scanning_filter_duplicates_test.cc b/tools/rootcanal/test/controller/le/le_scanning_filter_duplicates_test.cc
index 3387c8ad21..feed4edcd7 100644
--- a/tools/rootcanal/test/controller/le/le_scanning_filter_duplicates_test.cc
+++ b/tools/rootcanal/test/controller/le/le_scanning_filter_duplicates_test.cc
@@ -71,7 +71,7 @@ class LeScanningFilterDuplicates : public ::testing::Test {
void StartExtendedScan(FilterDuplicates filter_duplicates,
uint16_t duration = 0, uint16_t period = 0) {
- bluetooth::hci::PhyScanParameters param;
+ bluetooth::hci::ScanningPhyParameters param;
param.le_scan_type_ = LeScanType::ACTIVE;
param.le_scan_interval_ = 0x4;
param.le_scan_window_ = 0x4;
diff --git a/tools/rootcanal/test/controller/le/le_set_extended_scan_enable_test.cc b/tools/rootcanal/test/controller/le/le_set_extended_scan_enable_test.cc
index 79b9663619..278b9d06aa 100644
--- a/tools/rootcanal/test/controller/le/le_set_extended_scan_enable_test.cc
+++ b/tools/rootcanal/test/controller/le/le_set_extended_scan_enable_test.cc
@@ -33,10 +33,10 @@ class LeSetExtendedScanEnableTest : public ::testing::Test {
LinkLayerController controller_{address_, properties_};
};
-static PhyScanParameters MakePhyScanParameters(LeScanType scan_type,
- uint16_t scan_interval,
- uint16_t scan_window) {
- PhyScanParameters parameters;
+static ScanningPhyParameters MakeScanningPhyParameters(LeScanType scan_type,
+ uint16_t scan_interval,
+ uint16_t scan_window) {
+ ScanningPhyParameters parameters;
parameters.le_scan_type_ = scan_type;
parameters.le_scan_interval_ = scan_interval;
parameters.le_scan_window_ = scan_window;
@@ -44,22 +44,24 @@ static PhyScanParameters MakePhyScanParameters(LeScanType scan_type,
}
TEST_F(LeSetExtendedScanEnableTest, EnableUsingPublicAddress) {
- ASSERT_EQ(controller_.LeSetExtendedScanParameters(
- OwnAddressType::PUBLIC_DEVICE_ADDRESS,
- LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
- ErrorCode::SUCCESS);
+ ASSERT_EQ(
+ controller_.LeSetExtendedScanParameters(
+ OwnAddressType::PUBLIC_DEVICE_ADDRESS,
+ LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
+ ErrorCode::SUCCESS);
ASSERT_EQ(controller_.LeSetExtendedScanEnable(
true, FilterDuplicates::DISABLED, 0, 0),
ErrorCode::SUCCESS);
}
TEST_F(LeSetExtendedScanEnableTest, EnableUsingRandomAddress) {
- ASSERT_EQ(controller_.LeSetExtendedScanParameters(
- OwnAddressType::RANDOM_DEVICE_ADDRESS,
- LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
- ErrorCode::SUCCESS);
+ ASSERT_EQ(
+ controller_.LeSetExtendedScanParameters(
+ OwnAddressType::RANDOM_DEVICE_ADDRESS,
+ LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
+ ErrorCode::SUCCESS);
ASSERT_EQ(controller_.LeSetRandomAddress(Address{1}), ErrorCode::SUCCESS);
ASSERT_EQ(controller_.LeSetExtendedScanEnable(
true, FilterDuplicates::DISABLED, 0, 0),
@@ -67,11 +69,12 @@ TEST_F(LeSetExtendedScanEnableTest, EnableUsingRandomAddress) {
}
TEST_F(LeSetExtendedScanEnableTest, EnableUsingResolvableAddress) {
- ASSERT_EQ(controller_.LeSetExtendedScanParameters(
- OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS,
- LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
- ErrorCode::SUCCESS);
+ ASSERT_EQ(
+ controller_.LeSetExtendedScanParameters(
+ OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS,
+ LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
+ ErrorCode::SUCCESS);
ASSERT_EQ(controller_.LeSetRandomAddress(Address{1}), ErrorCode::SUCCESS);
ASSERT_EQ(controller_.LeSetExtendedScanEnable(
true, FilterDuplicates::DISABLED, 0, 0),
@@ -79,11 +82,12 @@ TEST_F(LeSetExtendedScanEnableTest, EnableUsingResolvableAddress) {
}
TEST_F(LeSetExtendedScanEnableTest, ResetEachPeriod) {
- ASSERT_EQ(controller_.LeSetExtendedScanParameters(
- OwnAddressType::PUBLIC_DEVICE_ADDRESS,
- LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
- ErrorCode::SUCCESS);
+ ASSERT_EQ(
+ controller_.LeSetExtendedScanParameters(
+ OwnAddressType::PUBLIC_DEVICE_ADDRESS,
+ LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
+ ErrorCode::SUCCESS);
ASSERT_EQ(controller_.LeSetExtendedScanEnable(
true, FilterDuplicates::RESET_EACH_PERIOD, 100, 1000),
ErrorCode::SUCCESS);
@@ -96,11 +100,12 @@ TEST_F(LeSetExtendedScanEnableTest, Disable) {
}
TEST_F(LeSetExtendedScanEnableTest, ValidDuration) {
- ASSERT_EQ(controller_.LeSetExtendedScanParameters(
- OwnAddressType::PUBLIC_DEVICE_ADDRESS,
- LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
- ErrorCode::SUCCESS);
+ ASSERT_EQ(
+ controller_.LeSetExtendedScanParameters(
+ OwnAddressType::PUBLIC_DEVICE_ADDRESS,
+ LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
+ ErrorCode::SUCCESS);
ASSERT_EQ(controller_.LeSetExtendedScanEnable(
true, FilterDuplicates::DISABLED, 127, 1),
@@ -108,11 +113,12 @@ TEST_F(LeSetExtendedScanEnableTest, ValidDuration) {
}
TEST_F(LeSetExtendedScanEnableTest, InvalidDuration) {
- ASSERT_EQ(controller_.LeSetExtendedScanParameters(
- OwnAddressType::PUBLIC_DEVICE_ADDRESS,
- LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
- ErrorCode::SUCCESS);
+ ASSERT_EQ(
+ controller_.LeSetExtendedScanParameters(
+ OwnAddressType::PUBLIC_DEVICE_ADDRESS,
+ LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
+ ErrorCode::SUCCESS);
ASSERT_EQ(controller_.LeSetExtendedScanEnable(
true, FilterDuplicates::RESET_EACH_PERIOD, 0, 0),
@@ -123,20 +129,22 @@ TEST_F(LeSetExtendedScanEnableTest, InvalidDuration) {
}
TEST_F(LeSetExtendedScanEnableTest, NoRandomAddress) {
- ASSERT_EQ(controller_.LeSetExtendedScanParameters(
- OwnAddressType::RANDOM_DEVICE_ADDRESS,
- LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
- ErrorCode::SUCCESS);
+ ASSERT_EQ(
+ controller_.LeSetExtendedScanParameters(
+ OwnAddressType::RANDOM_DEVICE_ADDRESS,
+ LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
+ ErrorCode::SUCCESS);
ASSERT_EQ(controller_.LeSetExtendedScanEnable(
true, FilterDuplicates::DISABLED, 0, 0),
ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
- ASSERT_EQ(controller_.LeSetExtendedScanParameters(
- OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS,
- LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
- ErrorCode::SUCCESS);
+ ASSERT_EQ(
+ controller_.LeSetExtendedScanParameters(
+ OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS,
+ LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
+ ErrorCode::SUCCESS);
ASSERT_EQ(controller_.LeSetExtendedScanEnable(
true, FilterDuplicates::DISABLED, 0, 0),
ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
diff --git a/tools/rootcanal/test/controller/le/le_set_extended_scan_parameters_test.cc b/tools/rootcanal/test/controller/le/le_set_extended_scan_parameters_test.cc
index 0c153ea1ac..3e1ab5390a 100644
--- a/tools/rootcanal/test/controller/le/le_set_extended_scan_parameters_test.cc
+++ b/tools/rootcanal/test/controller/le/le_set_extended_scan_parameters_test.cc
@@ -33,10 +33,10 @@ class LeSetExtendedScanParametersTest : public ::testing::Test {
LinkLayerController controller_{address_, properties_};
};
-static PhyScanParameters MakePhyScanParameters(LeScanType scan_type,
- uint16_t scan_interval,
- uint16_t scan_window) {
- PhyScanParameters parameters;
+static ScanningPhyParameters MakeScanningPhyParameters(LeScanType scan_type,
+ uint16_t scan_interval,
+ uint16_t scan_window) {
+ ScanningPhyParameters parameters;
parameters.le_scan_type_ = scan_type;
parameters.le_scan_interval_ = scan_interval;
parameters.le_scan_window_ = scan_window;
@@ -47,8 +47,8 @@ TEST_F(LeSetExtendedScanParametersTest, Success) {
ASSERT_EQ(controller_.LeSetExtendedScanParameters(
OwnAddressType::PUBLIC_DEVICE_ADDRESS,
LeScanningFilterPolicy::ACCEPT_ALL, 0x5,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200),
- MakePhyScanParameters(LeScanType::ACTIVE, 0x2000, 0x200)}),
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200),
+ MakeScanningPhyParameters(LeScanType::ACTIVE, 0x2000, 0x200)}),
ErrorCode::SUCCESS);
}
@@ -56,8 +56,8 @@ TEST_F(LeSetExtendedScanParametersTest, ScanningActive) {
ASSERT_EQ(controller_.LeSetExtendedScanParameters(
OwnAddressType::PUBLIC_DEVICE_ADDRESS,
LeScanningFilterPolicy::ACCEPT_ALL, 0x5,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200),
- MakePhyScanParameters(LeScanType::ACTIVE, 0x2000, 0x200)}),
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200),
+ MakeScanningPhyParameters(LeScanType::ACTIVE, 0x2000, 0x200)}),
ErrorCode::SUCCESS);
ASSERT_EQ(controller_.LeSetExtendedScanEnable(
true, FilterDuplicates::DISABLED, 0, 0),
@@ -66,17 +66,18 @@ TEST_F(LeSetExtendedScanParametersTest, ScanningActive) {
ASSERT_EQ(controller_.LeSetExtendedScanParameters(
OwnAddressType::PUBLIC_DEVICE_ADDRESS,
LeScanningFilterPolicy::ACCEPT_ALL, 0x5,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200),
- MakePhyScanParameters(LeScanType::ACTIVE, 0x2000, 0x200)}),
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200),
+ MakeScanningPhyParameters(LeScanType::ACTIVE, 0x2000, 0x200)}),
ErrorCode::COMMAND_DISALLOWED);
}
TEST_F(LeSetExtendedScanParametersTest, ReservedPhy) {
- ASSERT_EQ(controller_.LeSetExtendedScanParameters(
- OwnAddressType::PUBLIC_DEVICE_ADDRESS,
- LeScanningFilterPolicy::ACCEPT_ALL, 0x80,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
- ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
+ ASSERT_EQ(
+ controller_.LeSetExtendedScanParameters(
+ OwnAddressType::PUBLIC_DEVICE_ADDRESS,
+ LeScanningFilterPolicy::ACCEPT_ALL, 0x80,
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
+ ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE);
}
TEST_F(LeSetExtendedScanParametersTest, InvalidPhyParameters) {
@@ -85,19 +86,20 @@ TEST_F(LeSetExtendedScanParametersTest, InvalidPhyParameters) {
LeScanningFilterPolicy::ACCEPT_ALL, 0x1, {}),
ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
- ASSERT_EQ(controller_.LeSetExtendedScanParameters(
- OwnAddressType::PUBLIC_DEVICE_ADDRESS,
- LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200),
- MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
- ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
+ ASSERT_EQ(
+ controller_.LeSetExtendedScanParameters(
+ OwnAddressType::PUBLIC_DEVICE_ADDRESS,
+ LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200),
+ MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x200)}),
+ ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
}
TEST_F(LeSetExtendedScanParametersTest, InvalidScanInterval) {
ASSERT_EQ(controller_.LeSetExtendedScanParameters(
OwnAddressType::PUBLIC_DEVICE_ADDRESS,
LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x0, 0x200)}),
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x0, 0x200)}),
ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
}
@@ -105,14 +107,15 @@ TEST_F(LeSetExtendedScanParametersTest, InvalidScanWindow) {
ASSERT_EQ(controller_.LeSetExtendedScanParameters(
OwnAddressType::PUBLIC_DEVICE_ADDRESS,
LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x0)}),
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x0)}),
ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
- ASSERT_EQ(controller_.LeSetExtendedScanParameters(
- OwnAddressType::PUBLIC_DEVICE_ADDRESS,
- LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
- {MakePhyScanParameters(LeScanType::PASSIVE, 0x2000, 0x2001)}),
- ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
+ ASSERT_EQ(
+ controller_.LeSetExtendedScanParameters(
+ OwnAddressType::PUBLIC_DEVICE_ADDRESS,
+ LeScanningFilterPolicy::ACCEPT_ALL, 0x1,
+ {MakeScanningPhyParameters(LeScanType::PASSIVE, 0x2000, 0x2001)}),
+ ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
}
} // namespace rootcanal
diff --git a/tools/rootcanal/test/controller/le/test_helpers.h b/tools/rootcanal/test/controller/le/test_helpers.h
index 074e258d5c..4c9016c22c 100644
--- a/tools/rootcanal/test/controller/le/test_helpers.h
+++ b/tools/rootcanal/test/controller/le/test_helpers.h
@@ -49,18 +49,18 @@ MakeAdvertisingEventProperties(unsigned mask = 0) {
return set;
}
-[[maybe_unused]] static bluetooth::hci::LeCreateConnPhyScanParameters
+[[maybe_unused]] static bluetooth::hci::InitiatingPhyParameters
MakeInitiatingPhyParameters(uint16_t scan_interval, uint16_t scan_window,
uint16_t connection_interval_min,
uint16_t connection_interval_max,
uint16_t max_latency, uint16_t supervision_timeout,
uint16_t min_ce_length, uint16_t max_ce_length) {
- bluetooth::hci::LeCreateConnPhyScanParameters parameters;
+ bluetooth::hci::InitiatingPhyParameters parameters;
parameters.scan_interval_ = scan_interval;
parameters.scan_window_ = scan_window;
- parameters.conn_interval_min_ = connection_interval_min;
- parameters.conn_interval_max_ = connection_interval_max;
- parameters.conn_latency_ = max_latency;
+ parameters.connection_interval_min_ = connection_interval_min;
+ parameters.connection_interval_max_ = connection_interval_max;
+ parameters.max_latency_ = max_latency;
parameters.supervision_timeout_ = supervision_timeout;
parameters.min_ce_length_ = min_ce_length;
parameters.max_ce_length_ = max_ce_length;