summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy4
-rw-r--r--Android.bp30
-rw-r--r--TEST_MAPPING13
-rw-r--r--android/app/AndroidManifest.xml2
-rw-r--r--android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp11
-rw-r--r--android/app/jni/com_android_bluetooth_a2dp.cpp11
-rw-r--r--android/app/jni/com_android_bluetooth_a2dp_sink.cpp7
-rw-r--r--android/app/jni/com_android_bluetooth_avrcp_controller.cpp13
-rw-r--r--android/app/jni/com_android_bluetooth_avrcp_target.cpp14
-rw-r--r--android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp24
-rw-r--r--android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp8
-rw-r--r--android/app/jni/com_android_bluetooth_csip_set_coordinator.cpp17
-rw-r--r--android/app/jni/com_android_bluetooth_gatt.cpp24
-rw-r--r--android/app/jni/com_android_bluetooth_hap_client.cpp16
-rw-r--r--android/app/jni/com_android_bluetooth_hearing_aid.cpp13
-rw-r--r--android/app/jni/com_android_bluetooth_hfp.cpp9
-rw-r--r--android/app/jni/com_android_bluetooth_hfpclient.cpp11
-rw-r--r--android/app/jni/com_android_bluetooth_hid_device.cpp10
-rw-r--r--android/app/jni/com_android_bluetooth_hid_host.cpp12
-rw-r--r--android/app/jni/com_android_bluetooth_le_audio.cpp17
-rw-r--r--android/app/jni/com_android_bluetooth_pan.cpp8
-rw-r--r--android/app/jni/com_android_bluetooth_sdp.cpp12
-rw-r--r--android/app/jni/com_android_bluetooth_vc.cpp16
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/BassClientService.java391
-rw-r--r--android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java137
-rw-r--r--android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java40
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterProperties.java10
-rw-r--r--android/app/src/com/android/bluetooth/btservice/RemoteDevices.java11
-rw-r--r--android/app/src/com/android/bluetooth/le_audio/LeAudioService.java197
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/MsftAdvMonitor.java11
-rw-r--r--android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java24
-rw-r--r--android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java3
-rw-r--r--android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java2
-rw-r--r--android/app/src/com/android/bluetooth/opp/BluetoothOppService.java2
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java1
-rw-r--r--android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java1
-rw-r--r--android/app/src/com/android/bluetooth/tbs/TbsGatt.java3
-rw-r--r--android/app/src/com/android/bluetooth/vc/VolumeControlService.java249
-rw-r--r--android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java34
-rw-r--r--android/app/src/com/android/bluetooth/vc/VolumeControlStateMachine.java340
-rw-r--r--android/app/tests/unit/Android.bp1
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java501
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java39
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/ActiveDeviceManagerTest.java160
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/AdapterServiceTest.java20
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java16
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java2
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java304
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/le_scan/TransitionalScanHelperTest.java1
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java8
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java7
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceCleanupTest.java11
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceTest.java4
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java4
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java1168
-rw-r--r--android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java520
-rw-r--r--android/pandora/mmi2grpc/mmi2grpc/vcp.py76
-rw-r--r--android/pandora/server/configs/pts_bot_tests_config.json31
-rw-r--r--android/pandora/server/src/Server.kt1
-rw-r--r--android/pandora/server/src/Vcp.kt132
-rw-r--r--android/pandora/test/Android.bp8
-rw-r--r--flags/Android.bp9
-rw-r--r--flags/a2dp.aconfig11
-rw-r--r--flags/active_device_manager.aconfig10
-rw-r--r--flags/avrcp.aconfig7
-rw-r--r--flags/framework.aconfig18
-rw-r--r--flags/gap.aconfig17
-rw-r--r--flags/leaudio.aconfig26
-rw-r--r--flags/pairing.aconfig7
-rw-r--r--flags/sockets.aconfig8
-rw-r--r--floss/hcidoc/packets/build.rs2
-rw-r--r--floss/hcidoc/packets/lib.rs42
-rw-r--r--floss/hcidoc/src/groups/connections.rs232
-rw-r--r--floss/hcidoc/src/groups/informational.rs270
-rw-r--r--framework/Android.bp8
-rw-r--r--framework/api/system-current.txt24
-rw-r--r--framework/jarjar-rules.txt1
-rw-r--r--framework/java/android/bluetooth/BluetoothAdapter.java70
-rw-r--r--framework/java/android/bluetooth/BluetoothDevice.java5
-rw-r--r--framework/java/android/bluetooth/BluetoothLeAudio.java9
-rw-r--r--framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java5
-rw-r--r--framework/java/android/bluetooth/OobData.java4
-rw-r--r--framework/java/android/bluetooth/le/DistanceMeasurementSession.java4
-rw-r--r--framework/tests/bumble/Android.bp6
-rw-r--r--framework/tests/metrics/host/Android.bp2
-rw-r--r--framework/tests/unit/Android.bp6
-rw-r--r--framework/tests/unit/src/android/bluetooth/CallbackWrapperTest.java4
-rw-r--r--framework/tests/unit/src/android/bluetooth/le/ScanRecordTest.java56
-rw-r--r--pandora/interfaces/pandora_experimental/vcp.proto47
-rw-r--r--pandora/interfaces/python/Android.bp5
-rw-r--r--service/src/com/android/server/bluetooth/BluetoothManagerService.java141
-rw-r--r--service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java78
-rw-r--r--system/Android.bp4
-rw-r--r--system/audio_hal_interface/a2dp_encoding.h2
-rw-r--r--system/audio_hal_interface/a2dp_encoding_host.cc1
-rw-r--r--system/audio_hal_interface/aidl/a2dp/a2dp_encoding_aidl.h1
-rw-r--r--system/audio_hal_interface/aidl/a2dp/a2dp_provider_info.cc1
-rw-r--r--system/audio_hal_interface/aidl/client_interface_aidl.cc2
-rw-r--r--system/audio_hal_interface/aidl/hearing_aid_software_encoding_aidl.cc1
-rw-r--r--system/audio_hal_interface/aidl/le_audio_software_aidl.cc1
-rw-r--r--system/audio_hal_interface/hal_version_manager.cc1
-rw-r--r--system/audio_hal_interface/hfp_client_interface.cc1
-rw-r--r--system/audio_hal_interface/hidl/hearing_aid_software_encoding_hidl.cc1
-rw-r--r--system/audio_hal_interface/hidl/le_audio_software_hidl.cc2
-rw-r--r--system/audio_hal_interface/le_audio_software.cc1
-rw-r--r--system/bta/Android.bp9
-rw-r--r--system/bta/ag/bta_ag_at.cc1
-rw-r--r--system/bta/ag/bta_ag_int.h1
-rw-r--r--system/bta/av/bta_av_act.cc47
-rw-r--r--system/bta/av/bta_av_api.cc1
-rw-r--r--system/bta/av/bta_av_ci.cc1
-rw-r--r--system/bta/av/bta_av_int.h5
-rw-r--r--system/bta/av/bta_av_main.cc4
-rw-r--r--system/bta/av/bta_av_ssm.cc1
-rw-r--r--system/bta/dm/bta_dm_act.cc2
-rw-r--r--system/bta/dm/bta_dm_pm.cc1
-rw-r--r--system/bta/gatt/bta_gattc_api.cc1
-rw-r--r--system/bta/gatt/bta_gattc_db_storage.cc1
-rw-r--r--system/bta/gatt/bta_gattc_main.cc1
-rw-r--r--system/bta/gatt/bta_gattc_queue.cc1
-rw-r--r--system/bta/gatt/bta_gatts_queue.cc1
-rw-r--r--system/bta/gmap/gmap_client.cc1
-rw-r--r--system/bta/gmap/gmap_server.cc1
-rw-r--r--system/bta/has/has_client.cc1
-rw-r--r--system/bta/has/has_ctp.cc2
-rw-r--r--system/bta/hd/bta_hd_api.cc1
-rw-r--r--system/bta/hearing_aid/hearing_aid_audio_source.cc1
-rw-r--r--system/bta/hf_client/bta_hf_client_at.cc1
-rw-r--r--system/bta/hf_client/bta_hf_client_sdp.cc1
-rw-r--r--system/bta/hh/bta_hh_api.cc1
-rw-r--r--system/bta/hh/bta_hh_main.cc1
-rw-r--r--system/bta/hh/bta_hh_utils.cc1
-rw-r--r--system/bta/include/bta_api.h1
-rw-r--r--system/bta/jv/bta_jv_act.cc6
-rw-r--r--system/bta/le_audio/audio_hal_client/audio_sink_hal_client.cc1
-rw-r--r--system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc1
-rw-r--r--system/bta/le_audio/broadcaster/broadcaster.cc13
-rw-r--r--system/bta/le_audio/broadcaster/broadcaster_test.cc99
-rw-r--r--system/bta/le_audio/broadcaster/mock_state_machine.h1
-rw-r--r--system/bta/le_audio/broadcaster/state_machine.cc1
-rw-r--r--system/bta/le_audio/client.cc81
-rw-r--r--system/bta/le_audio/client_parser.cc1
-rw-r--r--system/bta/le_audio/codec_interface.cc2
-rw-r--r--system/bta/le_audio/codec_manager.cc81
-rw-r--r--system/bta/le_audio/codec_manager_test.cc34
-rw-r--r--system/bta/le_audio/content_control_id_keeper.cc1
-rw-r--r--system/bta/le_audio/devices.h1
-rw-r--r--system/bta/le_audio/devices_test.cc1
-rw-r--r--system/bta/le_audio/le_audio_client_test.cc78
-rw-r--r--system/bta/le_audio/le_audio_health_status.cc1
-rw-r--r--system/bta/le_audio/le_audio_log_history.cc2
-rw-r--r--system/bta/le_audio/le_audio_set_configuration_provider_json.cc1
-rw-r--r--system/bta/le_audio/le_audio_utils.cc1
-rw-r--r--system/bta/le_audio/storage_helper.cc1
-rw-r--r--system/bta/ras/ras_utils.cc1
-rw-r--r--system/bta/sys/bta_sys_main.cc1
-rw-r--r--system/bta/test/common/fake_osi.h1
-rw-r--r--system/bta/vc/device.cc1
-rw-r--r--system/bta/vc/vc.cc1
-rw-r--r--system/btcore/src/module.cc1
-rw-r--r--system/btcore/src/osi_module.cc1
-rw-r--r--system/btif/Android.bp2
-rw-r--r--system/btif/avrcp/avrcp_service.cc3
-rw-r--r--system/btif/co/bta_pan_co.cc1
-rw-r--r--system/btif/include/btif_common.h1
-rw-r--r--system/btif/src/bluetooth.cc4
-rw-r--r--system/btif/src/btif_a2dp.cc2
-rw-r--r--system/btif/src/btif_a2dp_source.cc165
-rw-r--r--system/btif/src/btif_av.cc1
-rw-r--r--system/btif/src/btif_hh.cc3
-rw-r--r--system/btif/src/btif_profile_queue.cc4
-rw-r--r--system/btif/src/btif_rc.cc1
-rw-r--r--system/build/Android.bp1
-rw-r--r--system/common/base_bind_unittest.cc2
-rw-r--r--system/device/src/device_iot_config.cc1
-rw-r--r--system/device/src/device_iot_config_int.cc1
-rw-r--r--system/device/src/interop.cc1
-rw-r--r--system/gd/Android.bp54
-rw-r--r--system/gd/README.md1
-rw-r--r--system/gd/common/audit_log.cc5
-rw-r--r--system/gd/common/byte_array_test.cc2
-rw-r--r--system/gd/common/circular_buffer_test.cc2
-rw-r--r--system/gd/common/lru_cache.h1
-rw-r--r--system/gd/common/metric_id_manager.cc2
-rw-r--r--system/gd/common/strings.h1
-rw-r--r--system/gd/common/sync_map_count_test.cc2
-rw-r--r--system/gd/docs/architecture/style_guide.md209
-rw-r--r--system/gd/docs/testing/gtest.md1
-rw-r--r--system/gd/dumpsys/Android.bp4
-rw-r--r--system/gd/dumpsys/internal/filter_internal.cc1
-rw-r--r--system/gd/dumpsys/internal/filter_internal_test.cc1
-rw-r--r--system/gd/dumpsys/reflection_schema.cc1
-rw-r--r--system/gd/facade/grpc_root_server.cc1
-rw-r--r--system/gd/grpc/grpc_event_queue.h1
-rw-r--r--system/gd/grpc/grpc_module.cc2
-rw-r--r--system/gd/hal/hci_hal_host.cc1
-rw-r--r--system/gd/hal/hci_hal_host_rootcanal.cc1
-rw-r--r--system/gd/hal/hci_hal_host_test.cc1
-rw-r--r--system/gd/hal/mgmt.cc2
-rw-r--r--system/gd/hal/ranging_hal_android.cc2
-rw-r--r--system/gd/hal/ranging_hal_host.cc2
-rw-r--r--system/gd/hci/acl_manager/assembler.h1
-rw-r--r--system/gd/hci/acl_manager/classic_acl_connection_test.cc1
-rw-r--r--system/gd/hci/acl_manager/round_robin_scheduler_test.cc1
-rw-r--r--system/gd/hci/distance_measurement_manager.cc236
-rw-r--r--system/gd/hci/event_checkers.h1
-rw-r--r--system/gd/hci/facade/le_advertising_manager_facade.cc1
-rw-r--r--system/gd/hci/facade/le_scanning_manager_facade.cc1
-rw-r--r--system/gd/hci/fuzz/acl_manager_fuzz_test.cc1
-rw-r--r--system/gd/hci/fuzz/fuzz_hci_layer.h1
-rw-r--r--system/gd/hci/fuzz/hci_layer_fuzz_test.cc1
-rw-r--r--system/gd/hci/hci_layer.cc11
-rw-r--r--system/gd/hci/hci_layer_test.cc1
-rw-r--r--system/gd/hci/hci_packets_fuzz_test.cc1
-rw-r--r--system/gd/hci/hci_packets_test.cc1
-rw-r--r--system/gd/hci/le_scanning_manager.cc1
-rw-r--r--system/gd/hci/le_scanning_reassembler.cc1
-rw-r--r--system/gd/metrics/chromeos/metrics.cc1
-rw-r--r--system/gd/metrics/counter_metrics.cc1
-rw-r--r--system/gd/module.h1
-rw-r--r--system/gd/neighbor/name_db.cc1
-rw-r--r--system/gd/neighbor/scan.cc1
-rw-r--r--system/gd/os/android/metrics.cc1
-rw-r--r--system/gd/os/android/system_properties.cc1
-rw-r--r--system/gd/os/android/wakelock_native.cc18
-rw-r--r--system/gd/os/chromeos/metrics.cc1
-rw-r--r--system/gd/os/chromeos/parameter_provider.cc2
-rw-r--r--system/gd/os/chromeos/wakelock_native.cc2
-rw-r--r--system/gd/os/handler.cc1
-rw-r--r--system/gd/os/handler_unittest.cc1
-rw-r--r--system/gd/os/host/metrics.cc2
-rw-r--r--system/gd/os/host/parameter_provider.cc2
-rw-r--r--system/gd/os/host/wakelock_native.cc2
-rw-r--r--system/gd/os/linux/metrics.cc2
-rw-r--r--system/gd/os/linux/parameter_provider.cc2
-rw-r--r--system/gd/os/linux/wakelock_native.cc2
-rw-r--r--system/gd/os/linux_generic/alarm.cc1
-rw-r--r--system/gd/os/linux_generic/files.cc2
-rw-r--r--system/gd/os/linux_generic/reactive_semaphore.cc1
-rw-r--r--system/gd/os/linux_generic/reactor.cc2
-rw-r--r--system/gd/os/linux_generic/reactor_unittest.cc1
-rw-r--r--system/gd/os/linux_generic/repeating_alarm.cc1
-rw-r--r--system/gd/os/linux_generic/thread.cc2
-rw-r--r--system/gd/os/linux_generic/wakelock_manager.cc1
-rw-r--r--system/gd/os/log.h30
-rw-r--r--system/gd/os/mock_queue.h1
-rw-r--r--system/gd/os/queue.h1
-rw-r--r--system/gd/os/rand.h2
-rw-r--r--system/gd/packet/Android.bp5
-rw-r--r--system/gd/packet/bit_inserter_unittest.cc2
-rw-r--r--system/gd/packet/fragmenting_inserter_unittest.cc2
-rw-r--r--system/gd/packet/packet_builder.h1
-rw-r--r--system/gd/packet/packet_struct.h1
-rw-r--r--system/gd/packet/parser/test/generated_packet_test.cc2
-rw-r--r--system/gd/packet/raw_builder.cc2
-rw-r--r--system/gd/rust/linux/stack/src/battery_service.rs56
-rw-r--r--system/gd/rust/linux/stack/src/bluetooth.rs139
-rw-r--r--system/gd/rust/linux/stack/src/bluetooth_gatt.rs17
-rw-r--r--system/gd/rust/linux/stack/src/bluetooth_media.rs8
-rw-r--r--system/gd/rust/linux/stack/src/lib.rs73
-rw-r--r--system/gd/rust/topshim/csis/csis_shim.cc8
-rw-r--r--system/gd/rust/topshim/hfp/hfp_shim.cc1
-rw-r--r--system/gd/rust/topshim/le_audio/le_audio_shim.cc12
-rw-r--r--system/gd/rust/topshim/vc/vc_shim.cc16
-rw-r--r--system/gd/shim/dumpsys.cc1
-rw-r--r--system/gd/stack_manager.cc1
-rw-r--r--system/gd/storage/device.cc1
-rw-r--r--system/gd/storage/legacy_config_file.cc1
-rw-r--r--system/gd/storage/mutation.cc2
-rw-r--r--system/gd/storage/mutation.h1
-rw-r--r--system/gd/storage/mutation_entry.cc2
-rw-r--r--system/gd/sysprops/sysprops_module.cc1
-rw-r--r--system/hci/src/packet_fragmenter.cc1
-rw-r--r--system/include/hardware/bt_vc.h1
-rw-r--r--system/internal_include/bt_target.h5
-rw-r--r--system/main/shim/config.cc1
-rw-r--r--system/main/stack_config.cc1
-rw-r--r--system/osi/src/alarm.cc1
-rw-r--r--system/osi/src/future.cc1
-rw-r--r--system/osi/src/internal/semaphore.cc1
-rw-r--r--system/osi/src/reactor.cc1
-rw-r--r--system/osi/src/socket.cc1
-rw-r--r--system/osi/src/stack_power_telemetry.cc2
-rw-r--r--system/osi/src/thread.cc1
-rw-r--r--system/osi/src/wakelock.cc1
-rw-r--r--system/packet/tests/fuzzers/Android.bp907
-rw-r--r--system/pdl/hci/hci_packets.pdl5
-rw-r--r--system/profile/avrcp/avrcp_internal.h4
-rw-r--r--system/profile/avrcp/connection_handler.cc8
-rw-r--r--system/profile/avrcp/tests/avrcp_connection_handler_test.cc8
-rw-r--r--system/profile/avrcp/tests/avrcp_test_helper.h2
-rw-r--r--system/profile/sdp/Android.bp60
-rw-r--r--system/profile/sdp/common/data_element_reader.cc238
-rw-r--r--system/profile/sdp/common/data_element_reader.h64
-rw-r--r--system/profile/sdp/common/test/data_element_reader_test.cc382
-rw-r--r--system/profile/sdp/sdp_common.h95
-rw-r--r--system/profile/sdp/sdp_logging_helper.h128
-rw-r--r--system/rust/src/core/ffi/module.cc2
-rw-r--r--system/rust/src/gatt/ffi/gatt_shim.cc1
-rw-r--r--system/stack/Android.bp85
-rw-r--r--system/stack/BUILD.gn2
-rw-r--r--system/stack/a2dp/a2dp_aac.cc1
-rw-r--r--system/stack/a2dp/a2dp_aac_decoder.cc1
-rw-r--r--system/stack/a2dp/a2dp_aac_encoder.cc1
-rw-r--r--system/stack/a2dp/a2dp_sbc_encoder.cc3
-rw-r--r--system/stack/a2dp/a2dp_vendor_aptx_encoder.cc1
-rw-r--r--system/stack/a2dp/a2dp_vendor_aptx_hd.cc1
-rw-r--r--system/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc1
-rw-r--r--system/stack/a2dp/a2dp_vendor_ldac.cc1
-rw-r--r--system/stack/a2dp/a2dp_vendor_ldac_decoder.cc1
-rw-r--r--system/stack/a2dp/a2dp_vendor_ldac_encoder.cc1
-rw-r--r--system/stack/a2dp/a2dp_vendor_opus.cc1
-rw-r--r--system/stack/a2dp/a2dp_vendor_opus_decoder.cc1
-rw-r--r--system/stack/a2dp/a2dp_vendor_opus_encoder.cc1
-rw-r--r--system/stack/acl/ble_acl.cc2
-rw-r--r--system/stack/acl/btm_acl.cc3
-rw-r--r--system/stack/acl/btm_pm.cc1
-rw-r--r--system/stack/avct/avct_api.cc87
-rw-r--r--system/stack/avct/avct_bcb_act.cc155
-rw-r--r--system/stack/avct/avct_ccb.cc10
-rw-r--r--system/stack/avct/avct_int.h54
-rw-r--r--system/stack/avct/avct_l2c.cc139
-rw-r--r--system/stack/avct/avct_l2c_br.cc168
-rw-r--r--system/stack/avct/avct_lcb.cc42
-rw-r--r--system/stack/avct/avct_lcb_act.cc34
-rw-r--r--system/stack/avdt/avdt_api.cc1
-rw-r--r--system/stack/avdt/avdt_msg.cc1
-rw-r--r--system/stack/avrc/avrc_api.cc30
-rw-r--r--system/stack/avrc/avrc_bld_ct.cc1
-rw-r--r--system/stack/avrc/avrc_bld_tg.cc6
-rw-r--r--system/stack/avrc/avrc_pars_ct.cc7
-rw-r--r--system/stack/avrc/avrc_pars_tg.cc1
-rw-r--r--system/stack/avrc/avrc_sdp.cc19
-rw-r--r--system/stack/avrc/avrc_utils.cc1
-rw-r--r--system/stack/btm/btm_ble_addr.cc1
-rw-r--r--system/stack/btm/btm_devctl.cc2
-rw-r--r--system/stack/btm/btm_iso_impl.h16
-rw-r--r--system/stack/btm/btm_sco_hci.cc1
-rw-r--r--system/stack/btm/btm_sco_hfp_hal_linux.cc1
-rw-r--r--system/stack/btm/btm_sec_cb.cc1
-rw-r--r--system/stack/btm/btm_security_client_interface.cc1
-rw-r--r--system/stack/btm/hfp_lc3_decoder.cc1
-rw-r--r--system/stack/btm/hfp_lc3_decoder_linux.cc1
-rw-r--r--system/stack/btm/hfp_lc3_encoder.cc1
-rw-r--r--system/stack/btm/hfp_lc3_encoder_linux.cc1
-rw-r--r--system/stack/btm/hfp_msbc_decoder.cc1
-rw-r--r--system/stack/btm/security_device_record.h2
-rw-r--r--system/stack/btu/main_thread.cc1
-rw-r--r--system/stack/connection_manager/connection_manager.cc (renamed from system/stack/gatt/connection_manager.cc)13
-rw-r--r--system/stack/connection_manager/connection_manager.h (renamed from system/stack/gatt/connection_manager.h)0
-rw-r--r--system/stack/fuzzers/avrc_fuzzer.cc13
-rw-r--r--system/stack/fuzzers/l2cap_fuzzer.cc3
-rw-r--r--system/stack/gatt/gatt_api.cc2
-rw-r--r--system/stack/gatt/gatt_int.h1
-rw-r--r--system/stack/gatt/gatt_main.cc2
-rw-r--r--system/stack/gatt/gatt_utils.cc2
-rw-r--r--system/stack/hid/hidd_api.cc1
-rw-r--r--system/stack/hid/hidh_api.cc1
-rw-r--r--system/stack/include/avct_api.h39
-rw-r--r--system/stack/include/avdt_api.h1
-rw-r--r--system/stack/include/avrc_api.h12
-rw-r--r--system/stack/include/bt_psm_types.h8
-rw-r--r--system/stack/include/l2cap_acl_interface.h3
-rw-r--r--system/stack/include/l2cap_hci_link_interface.h3
-rw-r--r--system/stack/l2cap/l2c_api.cc11
-rw-r--r--system/stack/l2cap/l2c_ble.cc13
-rw-r--r--system/stack/l2cap/l2c_ble_conn_params.cc4
-rw-r--r--system/stack/l2cap/l2c_csm.cc77
-rw-r--r--system/stack/l2cap/l2c_int.h11
-rw-r--r--system/stack/l2cap/l2c_link.cc47
-rw-r--r--system/stack/l2cap/l2c_main.cc5
-rw-r--r--system/stack/l2cap/l2c_utils.cc43
-rw-r--r--system/stack/pan/pan_api.cc2
-rw-r--r--system/stack/pan/pan_main.cc1
-rw-r--r--system/stack/pan/pan_utils.cc1
-rw-r--r--system/stack/smp/smp_br_main.cc1
-rw-r--r--system/stack/smp/smp_main.cc1
-rw-r--r--system/stack/srvc/srvc_dis.cc26
-rw-r--r--system/stack/srvc/srvc_dis_int.h5
-rw-r--r--system/stack/srvc/srvc_eng.cc127
-rw-r--r--system/stack/test/a2dp/a2dp_sbc_unittest.cc1
-rw-r--r--system/stack/test/a2dp/wav_reader.cc1
-rw-r--r--system/stack/test/btm_iso_test.cc78
-rw-r--r--system/stack/test/connection_manager_test.cc (renamed from system/stack/test/gatt_connection_manager_test.cc)3
-rw-r--r--system/stack/test/gatt/mock_gatt_utils_ref.cc2
-rw-r--r--system/stack/test/stack_avctp_test.cc128
-rw-r--r--system/stack/test/stack_l2cap_test.cc2
-rw-r--r--system/test/Android.bp7
-rw-r--r--system/test/common/jni_thread.cc2
-rw-r--r--system/test/common/main_handler.cc1
-rw-r--r--system/test/headless/adapter/adapter.cc1
-rw-r--r--system/test/headless/bt_stack_info.cc2
-rw-r--r--system/test/headless/discovery/discovery.cc1
-rw-r--r--system/test/headless/get_options.cc1
-rw-r--r--system/test/headless/headless.cc1
-rw-r--r--system/test/headless/interface.h1
-rw-r--r--system/test/headless/log.cc2
-rw-r--r--system/test/headless/main.cc1
-rw-r--r--system/test/headless/nop/nop.cc1
-rw-r--r--system/test/headless/property.cc1
-rw-r--r--system/test/headless/read/read.cc1
-rw-r--r--system/test/headless/scan/scan.cc1
-rw-r--r--system/test/headless/text.cc1
-rw-r--r--system/test/mock/mock_bta_av_api.h1
-rw-r--r--system/test/mock/mock_stack_avct_api.cc3
-rw-r--r--system/test/mock/mock_stack_avrc_api.cc6
-rw-r--r--system/test/mock/mock_stack_avrc_bld_tg.cc7
-rw-r--r--system/test/mock/mock_stack_avrc_pars.ct.cc8
-rw-r--r--system/test/mock/mock_stack_connection_manager.cc (renamed from system/test/mock/mock_stack_gatt_connection_manager.cc)8
-rw-r--r--system/test/mock/mock_stack_l2cap_api.cc5
-rw-r--r--system/test/mock/mock_stack_l2cap_api.h11
-rw-r--r--system/test/mock/mock_stack_l2cap_ble.cc6
-rw-r--r--system/test/mock/mock_stack_l2cap_ble.h14
-rw-r--r--system/test/mock/mock_stack_l2cap_link.cc20
-rw-r--r--system/test/mock/mock_stack_l2cap_utils.cc10
-rw-r--r--system/test/mock/mock_stack_srvc_dis.cc14
-rw-r--r--system/test/stub/osi.cc65
-rw-r--r--system/udrv/ulinux/uipc.cc1
-rw-r--r--tools/rootcanal/packets/hci_packets.pdl6
419 files changed, 5264 insertions, 6086 deletions
diff --git a/.clang-tidy b/.clang-tidy
new file mode 100644
index 0000000000..df0d649f1f
--- /dev/null
+++ b/.clang-tidy
@@ -0,0 +1,4 @@
+---
+CheckOptions:
+ - key: misc-include-cleaner.IgnoreHeaders
+ value: (fmt/.*|bits/pthread_types\.h)
diff --git a/Android.bp b/Android.bp
index 9fbf29d0df..71d6d402c2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -75,6 +75,27 @@ cc_defaults {
cpp_std: "c++20",
}
+// List of tidy checks that are enabled for cc targets.
+// Note that the goal is not to enable all checks, many of them will
+// appear as noise especially in the modernize-* range.
+bluetooth_tidy_checks = [
+ "-*",
+ "misc-*",
+
+ // This check implements detection of local variables which could be declared
+ // as const but are not.
+ "-misc-const-correctness",
+]
+
+// This default tidy checks that will be run against all the cc targets
+// developed by the Bluetooth team.
+cc_defaults {
+ name: "bluetooth_tidy",
+ tidy: true,
+ tidy_checks: bluetooth_tidy_checks,
+ tidy_checks_as_errors: bluetooth_tidy_checks,
+}
+
java_defaults {
name: "bluetooth_errorprone_rules",
errorprone: {
@@ -91,6 +112,7 @@ java_defaults {
"-Xep:DirectInvocationOnMock:ERROR",
"-Xep:EmptyBlockTag:ERROR",
"-Xep:EmptyCatch:ERROR",
+ "-Xep:EnumOrdinal:ERROR",
"-Xep:EqualsGetClass:ERROR",
"-Xep:EqualsHashCode:ERROR",
"-Xep:EqualsIncompatibleType:ERROR",
@@ -121,6 +143,8 @@ java_defaults {
"-Xep:NonAtomicVolatileUpdate:ERROR",
"-Xep:NonCanonicalType:ERROR",
"-Xep:NotJavadoc:ERROR",
+ "-Xep:NullablePrimitive:ERROR",
+ "-Xep:NullableVoid:ERROR",
"-Xep:ObjectEqualsForPrimitives:ERROR",
"-Xep:OperatorPrecedence:ERROR",
"-Xep:ReferenceEquality:ERROR",
@@ -147,8 +171,10 @@ java_defaults {
// Exclude generated files
"-XepExcludedPaths:.*/srcjars/.*",
- // The @InlineMe annotation is not available
- // "-Xep:InlineMeSuggester:OFF",
+ // The @InlineMe annotation could be made available, but it would
+ // apply on external facing API. This is not desired. For more
+ // context, see https://r.android.com/3303475
+ "-Xep:InlineMeSuggester:OFF",
],
},
}
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 5f21a9b800..5da35c4dc0 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -56,7 +56,7 @@
"name": "net_test_device_iot_config"
},
{
- "name": "net_test_gatt_conn_multiplexing"
+ "name": "net_test_conn_multiplexing"
},
{
"name": "net_test_hci"
@@ -108,9 +108,6 @@
"name": "bluetooth_test_common"
},
{
- "name": "bluetooth_test_sdp"
- },
- {
"name": "bluetooth_vc_test"
},
{
@@ -251,7 +248,7 @@
"name": "net_test_device_iot_config"
},
{
- "name": "net_test_gatt_conn_multiplexing"
+ "name": "net_test_conn_multiplexing"
},
{
"name": "net_test_stack"
@@ -273,9 +270,6 @@
"name": "bluetooth_test_common"
},
{
- "name": "bluetooth_test_sdp"
- },
- {
"name": "bluetooth_vc_test"
},
{
@@ -320,6 +314,9 @@
"name": "net_test_bta_jv"
},
{
+ "name": "net_test_stack_avctp"
+ },
+ {
"name": "asrc_resampler_test"
}
]
diff --git a/android/app/AndroidManifest.xml b/android/app/AndroidManifest.xml
index c77602c8a7..3416c8ff7f 100644
--- a/android/app/AndroidManifest.xml
+++ b/android/app/AndroidManifest.xml
@@ -203,7 +203,7 @@
</receiver>
<activity android:name="com.android.bluetooth.opp.BluetoothOppLauncherActivity"
android:process="@string/process"
- android:theme="@android:style/Theme.Material.Light.Dialog"
+ android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:label="@string/bt_share_picker_label"
android:enabled="false"
android:exported="true">
diff --git a/android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp b/android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp
index d1d48e93b7..b59bc9116f 100644
--- a/android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp
+++ b/android/app/jni/com_android_bluetooth_BluetoothQualityReport.cpp
@@ -16,14 +16,21 @@
#define LOG_TAG "BluetoothQualityReportJni"
-#include <string.h>
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/scoped_local_ref.h>
+#include <cstdint>
+#include <cstring>
+#include <mutex>
#include <shared_mutex>
+#include <vector>
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_bqr.h"
+#include "types/raw_address.h"
-using bluetooth::bqr::BluetoothQualityReportCallbacks;
using bluetooth::bqr::BluetoothQualityReportInterface;
namespace android {
diff --git a/android/app/jni/com_android_bluetooth_a2dp.cpp b/android/app/jni/com_android_bluetooth_a2dp.cpp
index f8a6f5480a..2d6e255d15 100644
--- a/android/app/jni/com_android_bluetooth_a2dp.cpp
+++ b/android/app/jni/com_android_bluetooth_a2dp.cpp
@@ -16,13 +16,24 @@
#define LOG_TAG "bluetooth-a2dp"
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_local_ref.h>
+
+#include <cerrno>
+#include <cstdint>
#include <cstring>
+#include <mutex>
#include <shared_mutex>
+#include <vector>
#include "btif/include/btif_av.h"
#include "btif/include/btif_util.h"
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_av.h"
+#include "types/raw_address.h"
namespace android {
static jmethodID method_onConnectionStateChanged;
diff --git a/android/app/jni/com_android_bluetooth_a2dp_sink.cpp b/android/app/jni/com_android_bluetooth_a2dp_sink.cpp
index 44f1fee6cc..f2347e9749 100644
--- a/android/app/jni/com_android_bluetooth_a2dp_sink.cpp
+++ b/android/app/jni/com_android_bluetooth_a2dp_sink.cpp
@@ -17,14 +17,21 @@
#define LOG_TAG "BluetoothA2dpSinkServiceJni"
#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_local_ref.h>
+#include <cerrno>
+#include <cstdint>
#include <cstring>
#include <mutex>
#include <shared_mutex>
#include "btif/include/btif_av.h"
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_av.h"
+#include "types/raw_address.h"
namespace android {
static jmethodID method_onConnectionStateChanged;
diff --git a/android/app/jni/com_android_bluetooth_avrcp_controller.cpp b/android/app/jni/com_android_bluetooth_avrcp_controller.cpp
index 0d29848e81..a0b80f7902 100644
--- a/android/app/jni/com_android_bluetooth_avrcp_controller.cpp
+++ b/android/app/jni/com_android_bluetooth_avrcp_controller.cpp
@@ -16,12 +16,21 @@
#define LOG_TAG "BluetoothAvrcpControllerJni"
-#include <string.h>
-
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_local_ref.h>
+
+#include <cerrno>
+#include <cstdint>
+#include <cstring>
+#include <mutex>
#include <shared_mutex>
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_rc.h"
+#include "types/raw_address.h"
namespace android {
static jmethodID method_onConnectionStateChanged;
diff --git a/android/app/jni/com_android_bluetooth_avrcp_target.cpp b/android/app/jni/com_android_bluetooth_avrcp_target.cpp
index 22f11e4345..9ed217aa2a 100644
--- a/android/app/jni/com_android_bluetooth_avrcp_target.cpp
+++ b/android/app/jni/com_android_bluetooth_avrcp_target.cpp
@@ -18,14 +18,24 @@
#include <base/functional/bind.h>
#include <base/functional/callback.h>
-#include <include/hardware/avrcp/avrcp.h>
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <cerrno>
+#include <cstdint>
+#include <cstring>
#include <map>
#include <mutex>
#include <shared_mutex>
+#include <string>
+#include <utility>
#include <vector>
-#include "./com_android_bluetooth.h"
+#include "com_android_bluetooth.h"
+#include "hardware/avrcp/avrcp.h"
+#include "hardware/avrcp/avrcp_common.h"
+#include "hardware/bluetooth.h"
+#include "types/raw_address.h"
// TODO(b/369381361) Enfore -Wmissing-prototypes
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
diff --git a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
index 050fc7b1a5..8e2f4e201d 100644
--- a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
+++ b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
@@ -17,21 +17,31 @@
#define LOG_TAG "BluetoothServiceJni"
-#include <dlfcn.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <hardware/bluetooth.h>
+#include <android/log.h>
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
#include <nativehelper/JNIPlatformHelp.h>
+#include <nativehelper/scoped_local_ref.h>
#include <pthread.h>
-#include <string.h>
#include <sys/prctl.h>
-#include <sys/stat.h>
+#include <array>
+#include <cerrno>
+#include <cstdint>
+#include <cstring>
+#include <mutex>
#include <shared_mutex>
+#include <string>
+#include <utility>
+#include <vector>
-#include "./com_android_bluetooth.h"
+#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_sock.h"
+#include "types/bluetooth/uuid.h"
#include "types/bt_transport.h"
+#include "types/raw_address.h"
// TODO(b/369381361) Enfore -Wmissing-prototypes
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
diff --git a/android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp b/android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp
index 330b55703e..5151bbff2f 100644
--- a/android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp
+++ b/android/app/jni/com_android_bluetooth_btservice_BluetoothKeystore.cpp
@@ -16,14 +16,18 @@
#define LOG_TAG "BluetoothKeystoreServiceJni"
-#include <string.h>
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <cstring>
+#include <mutex>
#include <shared_mutex>
+#include <string>
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_keystore.h"
-using bluetooth::bluetooth_keystore::BluetoothKeystoreCallbacks;
using bluetooth::bluetooth_keystore::BluetoothKeystoreInterface;
namespace android {
diff --git a/android/app/jni/com_android_bluetooth_csip_set_coordinator.cpp b/android/app/jni/com_android_bluetooth_csip_set_coordinator.cpp
index f083457386..0f30fb11ba 100644
--- a/android/app/jni/com_android_bluetooth_csip_set_coordinator.cpp
+++ b/android/app/jni/com_android_bluetooth_csip_set_coordinator.cpp
@@ -15,14 +15,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#define LOG_TAG "BluetoothCsipSetCoordinatorJni"
-#include <string.h>
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_local_ref.h>
+
+#include <cerrno>
+#include <cstdint>
+#include <cstring>
+#include <mutex>
#include <shared_mutex>
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_csis.h"
+#include "types/bluetooth/uuid.h"
+#include "types/raw_address.h"
+using bluetooth::Uuid;
using bluetooth::csis::ConnectionState;
using bluetooth::csis::CsisClientCallbacks;
using bluetooth::csis::CsisClientInterface;
@@ -40,8 +53,6 @@ static std::shared_timed_mutex interface_mutex;
static jobject mCallbacksObj = nullptr;
static std::shared_timed_mutex callbacks_mutex;
-using bluetooth::Uuid;
-
#define UUID_PARAMS(uuid) uuid_lsb(uuid), uuid_msb(uuid)
static uint64_t uuid_lsb(const Uuid& uuid) {
diff --git a/android/app/jni/com_android_bluetooth_gatt.cpp b/android/app/jni/com_android_bluetooth_gatt.cpp
index 0264da919f..9bde897040 100644
--- a/android/app/jni/com_android_bluetooth_gatt.cpp
+++ b/android/app/jni/com_android_bluetooth_gatt.cpp
@@ -18,20 +18,40 @@
#include <base/functional/bind.h>
#include <base/functional/callback.h>
-#include <string.h>
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_local_ref.h>
#include <array>
+#include <cerrno>
+#include <cstdint>
+#include <cstdio>
+#include <cstring>
+#include <functional>
#include <memory>
+#include <mutex>
#include <shared_mutex>
+#include <string>
+#include <utility>
+#include <vector>
#include "com_android_bluetooth.h"
#include "com_android_bluetooth_flags.h"
+#include "hardware/ble_advertiser.h"
+#include "hardware/ble_scanner.h"
+#include "hardware/bluetooth.h"
+#include "hardware/bt_common_types.h"
#include "hardware/bt_gatt.h"
+#include "hardware/bt_gatt_client.h"
+#include "hardware/bt_gatt_server.h"
#include "hardware/bt_gatt_types.h"
+#include "hardware/distance_measurement_interface.h"
#include "main/shim/le_scanning_manager.h"
#include "rust/cxx.h"
-#include "rust/src/gatt/ffi/gatt_shim.h"
#include "src/gatt/ffi.rs.h"
+#include "types/bluetooth/uuid.h"
+#include "types/raw_address.h"
// TODO(b/369381361) Enfore -Wmissing-prototypes
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
diff --git a/android/app/jni/com_android_bluetooth_hap_client.cpp b/android/app/jni/com_android_bluetooth_hap_client.cpp
index 295a207a4c..d2bdcbac8d 100644
--- a/android/app/jni/com_android_bluetooth_hap_client.cpp
+++ b/android/app/jni/com_android_bluetooth_hap_client.cpp
@@ -17,12 +17,24 @@
#define LOG_TAG "BluetoothHapClientJni"
-#include <string.h>
-
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_local_ref.h>
+
+#include <cerrno>
+#include <cstdint>
+#include <cstring>
+#include <mutex>
#include <shared_mutex>
+#include <utility>
+#include <variant>
+#include <vector>
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_has.h"
+#include "types/raw_address.h"
using bluetooth::has::ConnectionState;
using bluetooth::has::ErrorCode;
diff --git a/android/app/jni/com_android_bluetooth_hearing_aid.cpp b/android/app/jni/com_android_bluetooth_hearing_aid.cpp
index edf8dc5865..dbe2439ed4 100644
--- a/android/app/jni/com_android_bluetooth_hearing_aid.cpp
+++ b/android/app/jni/com_android_bluetooth_hearing_aid.cpp
@@ -16,12 +16,21 @@
#define LOG_TAG "BluetoothHearingAidServiceJni"
-#include <string.h>
-
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_local_ref.h>
+
+#include <cerrno>
+#include <cstdint>
+#include <cstring>
+#include <mutex>
#include <shared_mutex>
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_hearing_aid.h"
+#include "types/raw_address.h"
using bluetooth::hearing_aid::ConnectionState;
using bluetooth::hearing_aid::HearingAidCallbacks;
diff --git a/android/app/jni/com_android_bluetooth_hfp.cpp b/android/app/jni/com_android_bluetooth_hfp.cpp
index c1d982de17..0a53d42c6f 100644
--- a/android/app/jni/com_android_bluetooth_hfp.cpp
+++ b/android/app/jni/com_android_bluetooth_hfp.cpp
@@ -17,15 +17,22 @@
#define LOG_TAG "BluetoothHeadsetServiceJni"
#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_local_ref.h>
+#include <cerrno>
+#include <cstdint>
+#include <cstring>
#include <mutex>
#include <shared_mutex>
-#include "btif/include/btif_hf.h"
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bluetooth_headset_callbacks.h"
#include "hardware/bluetooth_headset_interface.h"
#include "hardware/bt_hf.h"
+#include "types/raw_address.h"
namespace android {
diff --git a/android/app/jni/com_android_bluetooth_hfpclient.cpp b/android/app/jni/com_android_bluetooth_hfpclient.cpp
index f42d8dd210..daf575204e 100644
--- a/android/app/jni/com_android_bluetooth_hfpclient.cpp
+++ b/android/app/jni/com_android_bluetooth_hfpclient.cpp
@@ -17,11 +17,20 @@
#define LOG_TAG "BluetoothHeadsetClientServiceJni"
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_local_ref.h>
+
+#include <cerrno>
+#include <cstring>
+#include <mutex>
#include <shared_mutex>
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_hf_client.h"
-#include "os/logging/log_adapter.h"
+#include "types/raw_address.h"
namespace android {
diff --git a/android/app/jni/com_android_bluetooth_hid_device.cpp b/android/app/jni/com_android_bluetooth_hid_device.cpp
index 6ff86e0530..5f2b98a2ce 100644
--- a/android/app/jni/com_android_bluetooth_hid_device.cpp
+++ b/android/app/jni/com_android_bluetooth_hid_device.cpp
@@ -16,10 +16,18 @@
#define LOG_TAG "BluetoothHidDeviceServiceJni"
-#include <string.h>
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/scoped_local_ref.h>
+
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_hd.h"
+#include "types/raw_address.h"
namespace android {
diff --git a/android/app/jni/com_android_bluetooth_hid_host.cpp b/android/app/jni/com_android_bluetooth_hid_host.cpp
index fcd28e5bbc..267eea8f84 100644
--- a/android/app/jni/com_android_bluetooth_hid_host.cpp
+++ b/android/app/jni/com_android_bluetooth_hid_host.cpp
@@ -16,13 +16,23 @@
#define LOG_TAG "BluetoothHidHostServiceJni"
-#include <string.h>
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/scoped_local_ref.h>
+#include <cstdint>
+#include <cstring>
+#include <mutex>
#include <shared_mutex>
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_hh.h"
+#include "types/ble_address_with_type.h"
+#include "types/bt_transport.h"
+#include "types/raw_address.h"
#include "utils/Log.h"
+
namespace android {
static jmethodID method_onConnectStateChanged;
diff --git a/android/app/jni/com_android_bluetooth_le_audio.cpp b/android/app/jni/com_android_bluetooth_le_audio.cpp
index 69c25d99b3..4ce436e5c4 100644
--- a/android/app/jni/com_android_bluetooth_le_audio.cpp
+++ b/android/app/jni/com_android_bluetooth_le_audio.cpp
@@ -16,14 +16,29 @@
#define LOG_TAG "BluetoothLeAudioServiceJni"
-#include <hardware/bluetooth.h>
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_local_ref.h>
+#include <algorithm>
#include <array>
+#include <cctype>
+#include <cerrno>
+#include <cstdint>
+#include <cstring>
+#include <map>
+#include <mutex>
#include <optional>
#include <shared_mutex>
+#include <string>
+#include <type_traits>
+#include <vector>
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_le_audio.h"
+#include "types/raw_address.h"
// TODO(b/369381361) Enfore -Wmissing-prototypes
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
diff --git a/android/app/jni/com_android_bluetooth_pan.cpp b/android/app/jni/com_android_bluetooth_pan.cpp
index 195b8fefc2..f0c78eac72 100644
--- a/android/app/jni/com_android_bluetooth_pan.cpp
+++ b/android/app/jni/com_android_bluetooth_pan.cpp
@@ -16,10 +16,16 @@
#define LOG_TAG "BluetoothPanServiceJni"
-#include <string.h>
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/scoped_local_ref.h>
+
+#include <cstring>
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_pan.h"
+#include "types/raw_address.h"
namespace android {
diff --git a/android/app/jni/com_android_bluetooth_sdp.cpp b/android/app/jni/com_android_bluetooth_sdp.cpp
index 1d49fca11a..e667dbcd8c 100644
--- a/android/app/jni/com_android_bluetooth_sdp.cpp
+++ b/android/app/jni/com_android_bluetooth_sdp.cpp
@@ -16,10 +16,20 @@
#define LOG_TAG "BluetoothSdpJni"
-#include <string.h>
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_local_ref.h>
+
+#include <cerrno>
+#include <cstdint>
+#include <cstring>
#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_sdp.h"
+#include "types/bluetooth/uuid.h"
+#include "types/raw_address.h"
using bluetooth::Uuid;
diff --git a/android/app/jni/com_android_bluetooth_vc.cpp b/android/app/jni/com_android_bluetooth_vc.cpp
index c998c0f7a1..39bd355dad 100644
--- a/android/app/jni/com_android_bluetooth_vc.cpp
+++ b/android/app/jni/com_android_bluetooth_vc.cpp
@@ -17,12 +17,22 @@
#define LOG_TAG "BluetoothVolumeControlServiceJni"
-#include <string.h>
-
+#include <bluetooth/log.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/scoped_local_ref.h>
+
+#include <cerrno>
+#include <cstdint>
+#include <cstring>
+#include <mutex>
#include <shared_mutex>
+#include <string>
-#include "./com_android_bluetooth.h"
+#include "com_android_bluetooth.h"
+#include "hardware/bluetooth.h"
#include "hardware/bt_vc.h"
+#include "types/raw_address.h"
using bluetooth::vc::ConnectionState;
using bluetooth::vc::VolumeControlCallbacks;
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
index 737cdb541c..7a0389ad2c 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
@@ -124,6 +124,7 @@ public class BassClientService extends ProfileService {
@VisibleForTesting static final int MESSAGE_SYNC_TIMEOUT = 1;
@VisibleForTesting static final int MESSAGE_BIG_MONITOR_TIMEOUT = 2;
@VisibleForTesting static final int MESSAGE_BROADCAST_MONITOR_TIMEOUT = 3;
+ @VisibleForTesting static final int MESSAGE_SYNC_LOST_TIMEOUT = 4;
/* 1 minute timeout for primary device reconnection in Private Broadcast case */
private static final int DIALING_OUT_TIMEOUT_MS = 60000;
@@ -137,6 +138,9 @@ public class BassClientService extends ProfileService {
// 5 minutes timeout for monitoring broadcaster
private static final Duration sBroadcasterMonitorTimeout = Duration.ofMinutes(5);
+ // 5 seconds timeout for sync Lost notification
+ private static final Duration sSyncLostTimeout = Duration.ofSeconds(5);
+
private enum PauseType {
HOST_INTENTIONAL,
SINK_UNINTENTIONAL
@@ -165,6 +169,8 @@ public class BassClientService extends ProfileService {
private final Map<BluetoothDevice, BluetoothLeBroadcastMetadata> mBroadcastMetadataMap =
new ConcurrentHashMap<>();
private final HashSet<BluetoothDevice> mPausedBroadcastSinks = new HashSet<>();
+ private final Map<BluetoothDevice, Pair<Integer, Integer>> mSinksWaitingForPast =
+ new HashMap<>();
private final Map<Integer, PauseType> mPausedBroadcastIds = new HashMap<>();
private final Deque<AddSourceData> mPendingAddSources = new ArrayDeque<>();
private final Map<Integer, HashSet<BluetoothDevice>> mLocalBroadcastReceivers =
@@ -216,39 +222,124 @@ public class BassClientService extends ProfileService {
clearAllSyncData();
break;
}
- case MESSAGE_BROADCAST_MONITOR_TIMEOUT:
- {
- log("MESSAGE_BROADCAST_MONITOR_TIMEOUT");
- int broadcastId = msg.arg1;
- List<Integer> activeSyncedSrc =
- new ArrayList<>(getActiveSyncedSources());
- if (activeSyncedSrc.contains(
- getSyncHandleForBroadcastId(broadcastId))) {
- break;
- }
- log("Notify broadcast source lost, broadcast id: " + broadcastId);
- mCallbacks.notifySourceLost(broadcastId);
- // fall through
- }
- case MESSAGE_BIG_MONITOR_TIMEOUT:
- {
- log("MESSAGE_BIG_MONITOR_TIMEOUT");
- int broadcastId = msg.arg1;
- stopSourceReceivers(broadcastId);
- synchronized (mSearchScanCallbackLock) {
- // when searching is stopped then clear all sync data
- if (mSearchScanCallback == null) {
- clearAllSyncData();
- }
- }
- break;
- }
default:
break;
}
}
};
+ @VisibleForTesting public final TimeoutHandler mTimeoutHandler = new TimeoutHandler();
+
+ @VisibleForTesting
+ public final class TimeoutHandler {
+ private final Map<Integer, Handler> mHandlers = new HashMap<>();
+
+ @VisibleForTesting
+ public Handler getOrCreateHandler(int broadcastId) {
+ return mHandlers.computeIfAbsent(
+ broadcastId,
+ key ->
+ new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MESSAGE_SYNC_LOST_TIMEOUT:
+ {
+ log("MESSAGE_SYNC_LOST_TIMEOUT");
+ // fall through
+ }
+ case MESSAGE_BROADCAST_MONITOR_TIMEOUT:
+ {
+ log("MESSAGE_BROADCAST_MONITOR_TIMEOUT");
+ List<Integer> activeSyncedSrc =
+ new ArrayList<>(getActiveSyncedSources());
+ if (activeSyncedSrc.contains(
+ getSyncHandleForBroadcastId(broadcastId))) {
+ break;
+ }
+ // Clear from cache to make possible sync again
+ // (only during active searching)
+ synchronized (mSearchScanCallbackLock) {
+ if (mSearchScanCallback != null) {
+ mCachedBroadcasts.remove(broadcastId);
+ }
+ }
+ log(
+ "Notify broadcast source lost, broadcast"
+ + " id: "
+ + broadcastId);
+ mCallbacks.notifySourceLost(broadcastId);
+ if (!isSinkUnintentionalPauseType(broadcastId)) {
+ break;
+ }
+ // fall through
+ }
+ case MESSAGE_BIG_MONITOR_TIMEOUT:
+ {
+ log("MESSAGE_BIG_MONITOR_TIMEOUT");
+ stopSourceReceivers(broadcastId);
+ break;
+ }
+ default:
+ break;
+ }
+ Handler handler = getOrCreateHandler(broadcastId);
+ if (!handler.hasMessagesOrCallbacks()) {
+ mHandlers.remove(broadcastId);
+ }
+ }
+ });
+ }
+
+ void start(int broadcastId, int msg, Duration duration) {
+ Handler handler = getOrCreateHandler(broadcastId);
+ log(
+ "Started timeout: "
+ + ("broadcastId: " + broadcastId)
+ + (", msg: " + msg)
+ + (", duration: " + duration));
+ handler.sendEmptyMessageDelayed(msg, duration.toMillis());
+ }
+
+ void stop(int broadcastId, int msg) {
+ if (!mHandlers.containsKey(broadcastId)) {
+ return;
+ }
+ Handler handler = getOrCreateHandler(broadcastId);
+ handler.removeMessages(msg);
+ if (!handler.hasMessagesOrCallbacks()) {
+ mHandlers.remove(broadcastId);
+ }
+ }
+
+ void stopAll() {
+ for (Handler handler : mHandlers.values()) {
+ handler.removeCallbacksAndMessages(null);
+ }
+ mHandlers.clear();
+ }
+
+ void stopAll(int msg) {
+ Iterator<Map.Entry<Integer, Handler>> iterator = mHandlers.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry<Integer, Handler> entry = iterator.next();
+ Handler handler = entry.getValue();
+ handler.removeMessages(msg);
+ if (!handler.hasMessagesOrCallbacks()) {
+ iterator.remove();
+ }
+ }
+ }
+
+ boolean isStarted(int broadcastId, int msg) {
+ if (!mHandlers.containsKey(broadcastId)) {
+ return false;
+ }
+ Handler handler = getOrCreateHandler(broadcastId);
+ return handler.hasMessages(msg);
+ }
+ }
+
public BassClientService(Context ctx) {
super(ctx);
}
@@ -710,6 +801,7 @@ public class BassClientService extends ProfileService {
}
mHandler.removeCallbacksAndMessages(null);
+ mTimeoutHandler.stopAll();
setBassClientService(null);
if (!leaudioBroadcastExtractPeriodicScannerFromStateMachine()) {
@@ -1010,6 +1102,24 @@ public class BassClientService extends ProfileService {
}
}
+ void syncRequestForPast(BluetoothDevice sink, int broadcastId, int sourceId) {
+ log(
+ "syncRequestForPast sink: "
+ + sink
+ + ", broadcastId: "
+ + broadcastId
+ + ", sourceId: "
+ + sourceId);
+
+ if (!leaudioBroadcastResyncHelper()) {
+ return;
+ }
+ synchronized (mSinksWaitingForPast) {
+ mSinksWaitingForPast.put(sink, new Pair<Integer, Integer>(broadcastId, sourceId));
+ }
+ addSelectSourceRequest(broadcastId, true);
+ }
+
private void localNotifyReceiveStateChanged(
BluetoothDevice sink, BluetoothLeBroadcastReceiveState receiveState) {
int broadcastId = receiveState.getBroadcastId();
@@ -1017,38 +1127,29 @@ public class BassClientService extends ProfileService {
&& !isLocalBroadcast(receiveState)
&& !isEmptyBluetoothDevice(receiveState.getSourceDevice())
&& !isHostPauseType(broadcastId)) {
- boolean isReadyToAutoResync = false;
- if (receiveState.getPaSyncState()
- == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED) {
- isReadyToAutoResync = true;
- } else {
- for (int i = 0; i < receiveState.getNumSubgroups(); i++) {
- Long syncState = receiveState.getBisSyncState().get(i);
- /* Synced to BIS */
- if (syncState != BassConstants.BIS_SYNC_NOT_SYNC_TO_BIS
- && syncState != BassConstants.BIS_SYNC_FAILED_SYNC_TO_BIG) {
- isReadyToAutoResync = true;
- break;
- }
- }
- }
- if (isReadyToAutoResync) {
- stopBigMonitoring(broadcastId, false);
+ if (isReceiverActive(receiveState)
+ || receiveState.getPaSyncState()
+ == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCINFO_REQUEST) {
+ mPausedBroadcastSinks.remove(sink);
+ if (isAllReceiversActive(broadcastId) && mPausedBroadcastSinks.isEmpty()) {
+ stopBigMonitoring(broadcastId, false);
+ }
} else if (!mPausedBroadcastIds.containsKey(broadcastId)) {
if (mCachedBroadcasts.containsKey(broadcastId)) {
addSelectSourceRequest(broadcastId, true);
mPausedBroadcastIds.put(broadcastId, PauseType.SINK_UNINTENTIONAL);
cacheSuspendingSources(broadcastId);
- mHandler.removeMessages(MESSAGE_BIG_MONITOR_TIMEOUT);
- Message newMsg = mHandler.obtainMessage(MESSAGE_BIG_MONITOR_TIMEOUT);
- newMsg.arg1 = broadcastId;
- log("Started MESSAGE_BIG_MONITOR_TIMEOUT");
- mHandler.sendMessageDelayed(newMsg, sBigMonitorTimeout.toMillis());
+ mTimeoutHandler.stop(broadcastId, MESSAGE_BIG_MONITOR_TIMEOUT);
+ mTimeoutHandler.start(
+ broadcastId, MESSAGE_BIG_MONITOR_TIMEOUT, sBigMonitorTimeout);
}
}
} else if (isEmptyBluetoothDevice(receiveState.getSourceDevice())) {
+ synchronized (mSinksWaitingForPast) {
+ mSinksWaitingForPast.remove(sink);
+ }
checkAndStopBigMonitoring();
}
@@ -1489,8 +1590,9 @@ public class BassClientService extends ProfileService {
if (toState == BluetoothProfile.STATE_DISCONNECTED) {
mPendingGroupOp.remove(device);
mPausedBroadcastSinks.remove(device);
-
- checkAndStopBigMonitoring();
+ synchronized (mSinksWaitingForPast) {
+ mSinksWaitingForPast.remove(device);
+ }
int bondState = mAdapterService.getBondState(device);
if (bondState == BluetoothDevice.BOND_NONE) {
@@ -1498,6 +1600,20 @@ public class BassClientService extends ProfileService {
removeStateMachine(device);
}
+ checkAndStopBigMonitoring();
+
+ if (getConnectedDevices().isEmpty()
+ || (mPausedBroadcastSinks.isEmpty()
+ && mSinksWaitingForPast.isEmpty()
+ && !isAnyConnectedDeviceSwitchingSource())) {
+ synchronized (mSearchScanCallbackLock) {
+ // when searching is stopped then clear all sync data
+ if (mSearchScanCallback == null) {
+ clearAllSyncData();
+ }
+ }
+ }
+
/* Restore allowed context mask for unicast in case if last connected broadcast
* delegator device which has external source disconnectes.
*/
@@ -1832,8 +1948,10 @@ public class BassClientService extends ProfileService {
TAG,
"Broadcast Source Found: Broadcast ID: " + broadcastId);
- if (broadcastId != BassConstants.INVALID_BROADCAST_ID
- && !mCachedBroadcasts.containsKey(broadcastId)) {
+ if (broadcastId == BassConstants.INVALID_BROADCAST_ID) {
+ return;
+ }
+ if (!mCachedBroadcasts.containsKey(broadcastId)) {
log("selectBroadcastSource: broadcastId " + broadcastId);
mCachedBroadcasts.put(broadcastId, result);
if (leaudioBroadcastExtractPeriodicScannerFromStateMachine()) {
@@ -1848,6 +1966,14 @@ public class BassClientService extends ProfileService {
}
}
}
+ } else if (leaudioBroadcastResyncHelper()
+ && mTimeoutHandler.isStarted(
+ broadcastId, MESSAGE_SYNC_LOST_TIMEOUT)) {
+ mTimeoutHandler.stop(broadcastId, MESSAGE_SYNC_LOST_TIMEOUT);
+ mTimeoutHandler.start(
+ broadcastId,
+ MESSAGE_SYNC_LOST_TIMEOUT,
+ sSyncLostTimeout);
}
}
}
@@ -1970,6 +2096,7 @@ public class BassClientService extends ProfileService {
private void clearAllSyncData() {
log("clearAllSyncData");
+ mTimeoutHandler.stopAll(MESSAGE_SYNC_LOST_TIMEOUT);
mSourceSyncRequestsQueue.clear();
mSyncFailureCounter.clear();
mPendingSourcesToAdd.clear();
@@ -2047,7 +2174,7 @@ public class BassClientService extends ProfileService {
}
}
} else {
- mHandler.removeMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ mTimeoutHandler.stop(broadcastId, MESSAGE_BROADCAST_MONITOR_TIMEOUT);
}
// update valid sync handle in mPeriodicAdvCallbacksMap
@@ -2061,6 +2188,41 @@ public class BassClientService extends ProfileService {
}
mBisDiscoveryCounterMap.put(syncHandle, MAX_BIS_DISCOVERY_TRIES_NUM);
+ synchronized (mSinksWaitingForPast) {
+ Iterator<Map.Entry<BluetoothDevice, Pair<Integer, Integer>>> iterator =
+ mSinksWaitingForPast.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry<BluetoothDevice, Pair<Integer, Integer>> entry = iterator.next();
+ BluetoothDevice sinkDevice = entry.getKey();
+ int broadcastIdForPast = entry.getValue().first;
+ if (broadcastId == broadcastIdForPast) {
+ int sourceId = entry.getValue().second;
+ synchronized (mStateMachines) {
+ BassClientStateMachine sm = getOrCreateStateMachine(sinkDevice);
+ Message message =
+ sm.obtainMessage(
+ BassClientStateMachine.INITIATE_PA_SYNC_TRANSFER);
+ message.arg1 = syncHandle;
+ message.arg2 = sourceId;
+ sm.sendMessage(message);
+ }
+ synchronized (mPendingSourcesToAdd) {
+ Iterator<AddSourceData> addIterator =
+ mPendingSourcesToAdd.iterator();
+ while (addIterator.hasNext()) {
+ AddSourceData pendingSourcesToAdd = addIterator.next();
+ if (pendingSourcesToAdd.mSourceMetadata.getBroadcastId()
+ == broadcastId
+ && pendingSourcesToAdd.mSink.equals(sinkDevice)) {
+ addIterator.remove();
+ }
+ }
+ }
+ iterator.remove();
+ }
+ }
+ }
+
synchronized (mPendingSourcesToAdd) {
Iterator<AddSourceData> iterator = mPendingSourcesToAdd.iterator();
while (iterator.hasNext()) {
@@ -2100,11 +2262,12 @@ public class BassClientService extends ProfileService {
mSyncFailureCounter.put(broadcastId, failsCounter);
}
if (isSinkUnintentionalPauseType(broadcastId)) {
- if (!mHandler.hasMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT)) {
- Message newMsg = mHandler.obtainMessage(MESSAGE_BROADCAST_MONITOR_TIMEOUT);
- newMsg.arg1 = broadcastId;
- log("Started MESSAGE_BROADCAST_MONITOR_TIMEOUT");
- mHandler.sendMessageDelayed(newMsg, sBroadcasterMonitorTimeout.toMillis());
+ if (!mTimeoutHandler.isStarted(
+ broadcastId, MESSAGE_BROADCAST_MONITOR_TIMEOUT)) {
+ mTimeoutHandler.start(
+ broadcastId,
+ MESSAGE_BROADCAST_MONITOR_TIMEOUT,
+ sBroadcasterMonitorTimeout);
}
addSelectSourceRequest(broadcastId, true);
} else {
@@ -2183,23 +2346,31 @@ public class BassClientService extends ProfileService {
int failsCounter = mSyncFailureCounter.getOrDefault(broadcastId, 0) + 1;
mSyncFailureCounter.put(broadcastId, failsCounter);
}
+ mTimeoutHandler.stop(broadcastId, MESSAGE_SYNC_LOST_TIMEOUT);
if (isSinkUnintentionalPauseType(broadcastId)) {
- if (!mHandler.hasMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT)) {
- Message newMsg = mHandler.obtainMessage(MESSAGE_BROADCAST_MONITOR_TIMEOUT);
- newMsg.arg1 = broadcastId;
- log("Started MESSAGE_BROADCAST_MONITOR_TIMEOUT");
- mHandler.sendMessageDelayed(newMsg, sBroadcasterMonitorTimeout.toMillis());
+ if (!mTimeoutHandler.isStarted(
+ broadcastId, MESSAGE_BROADCAST_MONITOR_TIMEOUT)) {
+ mTimeoutHandler.start(
+ broadcastId,
+ MESSAGE_BROADCAST_MONITOR_TIMEOUT,
+ sBroadcasterMonitorTimeout);
}
addSelectSourceRequest(broadcastId, true);
} else {
- // Clear from cache to make possible sync again (only during active searching)
- synchronized (mSearchScanCallbackLock) {
- if (mSearchScanCallback != null) {
- mCachedBroadcasts.remove(broadcastId);
+ if (leaudioBroadcastResyncHelper()) {
+ mTimeoutHandler.start(
+ broadcastId, MESSAGE_SYNC_LOST_TIMEOUT, sSyncLostTimeout);
+ } else {
+ // Clear from cache to make possible sync again (only during active
+ // searching)
+ synchronized (mSearchScanCallbackLock) {
+ if (mSearchScanCallback != null) {
+ mCachedBroadcasts.remove(broadcastId);
+ }
}
+ log("Notify broadcast source lost, broadcast id: " + broadcastId);
+ mCallbacks.notifySourceLost(broadcastId);
}
- log("Notify broadcast source lost, broadcast id: " + broadcastId);
- mCallbacks.notifySourceLost(broadcastId);
}
}
}
@@ -2480,7 +2651,7 @@ public class BassClientService extends ProfileService {
+ broadcastId
+ ", hasPriority: "
+ hasPriority);
-
+ mTimeoutHandler.stop(broadcastId, MESSAGE_SYNC_LOST_TIMEOUT);
ScanResult scanRes = getCachedBroadcast(broadcastId);
if (scanRes != null) {
ScanRecord scanRecord = scanRes.getScanRecord();
@@ -2572,9 +2743,11 @@ public class BassClientService extends ProfileService {
cancelActiveSync(syncHandle);
} else {
Boolean canceledActiveSync = false;
+ int broadcstIdToLostMonitoring = BassConstants.INVALID_BROADCAST_ID;
for (int syncHandle : activeSyncedSrc) {
if (!isAnyReceiverSyncedToBroadcast(getBroadcastIdForSyncHandle(syncHandle))) {
canceledActiveSync = true;
+ broadcstIdToLostMonitoring = getBroadcastIdForSyncHandle(syncHandle);
cancelActiveSync(syncHandle);
break;
}
@@ -2582,8 +2755,11 @@ public class BassClientService extends ProfileService {
if (!canceledActiveSync) {
int syncHandle = activeSyncedSrc.get(0);
// removing the 1st synced source before proceeding to add new
+ broadcstIdToLostMonitoring = getBroadcastIdForSyncHandle(syncHandle);
cancelActiveSync(syncHandle);
}
+ mTimeoutHandler.start(
+ broadcstIdToLostMonitoring, MESSAGE_SYNC_LOST_TIMEOUT, sSyncLostTimeout);
}
}
@@ -3447,14 +3623,13 @@ public class BassClientService extends ProfileService {
return;
}
log("stopBigMonitoring");
- mHandler.removeMessages(MESSAGE_BIG_MONITOR_TIMEOUT);
- mHandler.removeMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT);
-
mPausedBroadcastSinks.clear();
Iterator<Integer> iterator = mPausedBroadcastIds.keySet().iterator();
while (iterator.hasNext()) {
int pausedBroadcastId = iterator.next();
+ mTimeoutHandler.stop(pausedBroadcastId, MESSAGE_BIG_MONITOR_TIMEOUT);
+ mTimeoutHandler.stop(pausedBroadcastId, MESSAGE_BROADCAST_MONITOR_TIMEOUT);
iterator.remove();
synchronized (mSearchScanCallbackLock) {
// when searching is stopped then stop active sync
@@ -3475,8 +3650,8 @@ public class BassClientService extends ProfileService {
while (iterator.hasNext()) {
int pausedBroadcastId = iterator.next();
if (!isAnyReceiverSyncedToBroadcast(pausedBroadcastId)) {
- mHandler.removeMessages(MESSAGE_BIG_MONITOR_TIMEOUT);
- mHandler.removeMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ mTimeoutHandler.stop(pausedBroadcastId, MESSAGE_BIG_MONITOR_TIMEOUT);
+ mTimeoutHandler.stop(pausedBroadcastId, MESSAGE_BROADCAST_MONITOR_TIMEOUT);
iterator.remove();
synchronized (mSearchScanCallbackLock) {
// when searching is stopped then stop active sync
@@ -3494,8 +3669,8 @@ public class BassClientService extends ProfileService {
return;
}
log("stopBigMonitoring broadcastId: " + broadcastId + ", hostInitiated: " + hostInitiated);
- mHandler.removeMessages(MESSAGE_BIG_MONITOR_TIMEOUT);
- mHandler.removeMessages(MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ mTimeoutHandler.stop(broadcastId, MESSAGE_BIG_MONITOR_TIMEOUT);
+ mTimeoutHandler.stop(broadcastId, MESSAGE_BROADCAST_MONITOR_TIMEOUT);
if (hostInitiated) {
mPausedBroadcastIds.put(broadcastId, PauseType.HOST_INTENTIONAL);
} else {
@@ -3579,14 +3754,23 @@ public class BassClientService extends ProfileService {
.filter(e -> e.getBroadcastId() == metadata.getBroadcastId())
.findAny();
+ if (leaudioBroadcastResyncHelper()
+ && receiveState.isPresent()
+ && (receiveState.get().getPaSyncState()
+ == BluetoothLeBroadcastReceiveState
+ .PA_SYNC_STATE_SYNCINFO_REQUEST
+ || receiveState.get().getPaSyncState()
+ == BluetoothLeBroadcastReceiveState
+ .PA_SYNC_STATE_SYNCHRONIZED)) {
+ iterator.remove();
+ continue;
+ }
+
List<Integer> activeSyncedSrc = getActiveSyncedSources();
if (receiveState.isPresent()
&& (!leaudioBroadcastResyncHelper()
|| isLocalBroadcast(metadata)
- || receiveState.get().getPaSyncState()
- == BluetoothLeBroadcastReceiveState
- .PA_SYNC_STATE_SYNCHRONIZED
|| activeSyncedSrc.contains(
getSyncHandleForBroadcastId(metadata.getBroadcastId())))) {
int sourceId = receiveState.get().getSourceId();
@@ -3743,26 +3927,51 @@ public class BassClientService extends ProfileService {
return false;
}
+ private boolean isReceiverActive(BluetoothLeBroadcastReceiveState receiveState) {
+ if (receiveState.getPaSyncState()
+ == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCHRONIZED) {
+ return true;
+ } else {
+ for (int i = 0; i < receiveState.getNumSubgroups(); i++) {
+ Long syncState = receiveState.getBisSyncState().get(i);
+ /* Synced to BIS */
+ if (syncState != BassConstants.BIS_SYNC_NOT_SYNC_TO_BIS
+ && syncState != BassConstants.BIS_SYNC_FAILED_SYNC_TO_BIG) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private Set<Integer> getExternalBroadcastsActiveOnSinks() {
HashSet<Integer> syncedBroadcasts = new HashSet<>();
for (BluetoothDevice device : getConnectedDevices()) {
for (BluetoothLeBroadcastReceiveState receiveState : getAllSources(device)) {
- if (!isLocalBroadcast(receiveState)) {
- for (int i = 0; i < receiveState.getNumSubgroups(); i++) {
- Long syncState = receiveState.getBisSyncState().get(i);
- /* Synced to BIS */
- if (syncState != BassConstants.BIS_SYNC_NOT_SYNC_TO_BIS
- && syncState != BassConstants.BIS_SYNC_FAILED_SYNC_TO_BIG) {
- syncedBroadcasts.add(receiveState.getBroadcastId());
- log("getExternalBroadcastsActiveOnSinks: " + receiveState);
- }
- }
+ if (isLocalBroadcast(receiveState)) {
+ continue;
+ }
+ if (isReceiverActive(receiveState)) {
+ syncedBroadcasts.add(receiveState.getBroadcastId());
+ log("getExternalBroadcastsActiveOnSinks: " + receiveState);
}
}
}
return syncedBroadcasts;
}
+ private boolean isAllReceiversActive(int broadcastId) {
+ for (BluetoothDevice device : getConnectedDevices()) {
+ for (BluetoothLeBroadcastReceiveState receiveState : getAllSources(device)) {
+ if (receiveState.getBroadcastId() == broadcastId
+ && !isReceiverActive(receiveState)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
/** Get sink devices synced to the broadcasts */
public List<BluetoothDevice> getSyncedBroadcastSinks() {
List<BluetoothDevice> activeSinks = new ArrayList<>();
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
index adca0a07b6..b59ff2fcd2 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
@@ -84,8 +84,7 @@ import java.util.Scanner;
import java.util.UUID;
import java.util.stream.IntStream;
-@VisibleForTesting
-public class BassClientStateMachine extends StateMachine {
+class BassClientStateMachine extends StateMachine {
private static final String TAG = "BassClientStateMachine";
@VisibleForTesting static final byte[] REMOTE_SCAN_STOP = {00};
@VisibleForTesting static final byte[] REMOTE_SCAN_START = {01};
@@ -113,6 +112,7 @@ public class BassClientStateMachine extends StateMachine {
static final int REACHED_MAX_SOURCE_LIMIT = 16;
static final int SWITCH_BCAST_SOURCE = 17;
static final int CANCEL_PENDING_SOURCE_OPERATION = 18;
+ static final int INITIATE_PA_SYNC_TRANSFER = 19;
// NOTE: the value is not "final" - it is modified in the unit tests
@VisibleForTesting private int mConnectTimeoutMs;
@@ -816,69 +816,80 @@ public class BassClientStateMachine extends StateMachine {
int state = recvState.getPaSyncState();
if (state == BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCINFO_REQUEST) {
log("Initiate PAST procedure");
- PeriodicAdvertisementResult result =
- mService.getPeriodicAdvertisementResult(
- recvState.getSourceDevice(), recvState.getBroadcastId());
- if (result != null) {
- int syncHandle = result.getSyncHandle();
- log("processPASyncState: syncHandle " + result.getSyncHandle());
- if (syncHandle != BassConstants.INVALID_SYNC_HANDLE) {
- serviceData = 0x000000FF & recvState.getSourceId();
- serviceData = serviceData << 8;
- // advA matches EXT_ADV_ADDRESS
- // also matches source address (as we would have written)
- serviceData =
- serviceData & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_EXT_ADV_ADDRESS);
- serviceData =
- serviceData
- & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS);
- log(
- "Initiate PAST for: "
- + mDevice
- + ", syncHandle: "
- + syncHandle
- + "serviceData"
- + serviceData);
- BluetoothMethodProxy.getInstance()
- .periodicAdvertisingManagerTransferSync(
- BassClientPeriodicAdvertisingManager
- .getPeriodicAdvertisingManager(),
- mDevice,
- serviceData,
- syncHandle);
- }
+ int sourceId = recvState.getSourceId();
+ BluetoothLeBroadcastMetadata currentMetadata = getCurrentBroadcastMetadata(sourceId);
+ if (mService.isLocalBroadcast(currentMetadata)) {
+ int advHandle = currentMetadata.getSourceAdvertisingSid();
+ serviceData = 0x000000FF & sourceId;
+ serviceData = serviceData << 8;
+ // Address we set in the Source Address can differ from the address in the air
+ serviceData =
+ serviceData | BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS;
+ log(
+ "Initiate local broadcast PAST for: "
+ + mDevice
+ + ", advSID/Handle: "
+ + advHandle
+ + ", serviceData: "
+ + serviceData);
+ BluetoothMethodProxy.getInstance()
+ .periodicAdvertisingManagerTransferSetInfo(
+ BassClientPeriodicAdvertisingManager
+ .getPeriodicAdvertisingManager(),
+ mDevice,
+ serviceData,
+ advHandle,
+ mLocalPeriodicAdvCallback);
} else {
- BluetoothLeBroadcastMetadata currentMetadata =
- getCurrentBroadcastMetadata(recvState.getSourceId());
- if (mService.isLocalBroadcast(currentMetadata)) {
- int advHandle = currentMetadata.getSourceAdvertisingSid();
- serviceData = 0x000000FF & recvState.getSourceId();
- serviceData = serviceData << 8;
- // Address we set in the Source Address can differ from the address in the air
- serviceData =
- serviceData | BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS;
- log(
- "Initiate local broadcast PAST for: "
- + mDevice
- + ", advSID/Handle: "
- + advHandle
- + ", serviceData: "
- + serviceData);
- BluetoothMethodProxy.getInstance()
- .periodicAdvertisingManagerTransferSetInfo(
- BassClientPeriodicAdvertisingManager
- .getPeriodicAdvertisingManager(),
- mDevice,
- serviceData,
- advHandle,
- mLocalPeriodicAdvCallback);
- } else {
- Log.e(TAG, "There is no valid sync handle for this Source");
+ int broadcastId = recvState.getBroadcastId();
+ PeriodicAdvertisementResult result =
+ mService.getPeriodicAdvertisementResult(
+ recvState.getSourceDevice(), broadcastId);
+ if (result != null) {
+ int syncHandle = result.getSyncHandle();
+ if (syncHandle != BassConstants.INVALID_SYNC_HANDLE) {
+ initiatePaSyncTransfer(syncHandle, sourceId);
+ return;
+ }
}
+ mService.syncRequestForPast(mDevice, broadcastId, sourceId);
}
}
}
+ private void initiatePaSyncTransfer(int syncHandle, int sourceId) {
+ if (syncHandle != BassConstants.INVALID_SYNC_HANDLE
+ && sourceId != BassConstants.INVALID_SOURCE_ID) {
+ int serviceData = 0x000000FF & sourceId;
+ serviceData = serviceData << 8;
+ // advA matches EXT_ADV_ADDRESS
+ // also matches source address (as we would have written)
+ serviceData = serviceData & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_EXT_ADV_ADDRESS);
+ serviceData =
+ serviceData & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS);
+ log(
+ "Initiate PAST for: "
+ + mDevice
+ + ", syncHandle: "
+ + syncHandle
+ + ", serviceData: "
+ + serviceData);
+ BluetoothMethodProxy.getInstance()
+ .periodicAdvertisingManagerTransferSync(
+ BassClientPeriodicAdvertisingManager.getPeriodicAdvertisingManager(),
+ mDevice,
+ serviceData,
+ syncHandle);
+ } else {
+ Log.e(
+ TAG,
+ "Invalid syncHandle or sourceId for PAST, syncHandle: "
+ + syncHandle
+ + ", sourceId: "
+ + sourceId);
+ }
+ }
+
private void processSyncStateChangeStats(BluetoothLeBroadcastReceiveState recvState) {
int sourceId = recvState.getSourceId();
BluetoothLeBroadcastMetadata metaData = getCurrentBroadcastMetadata(sourceId);
@@ -2350,6 +2361,11 @@ public class BassClientStateMachine extends StateMachine {
int broadcastId = message.arg1;
cancelPendingSourceOperation(broadcastId);
break;
+ case INITIATE_PA_SYNC_TRANSFER:
+ int syncHandle = message.arg1;
+ int sourceIdForPast = message.arg2;
+ initiatePaSyncTransfer(syncHandle, sourceIdForPast);
+ break;
default:
log("CONNECTED: not handled message:" + message.what);
return NOT_HANDLED;
@@ -2539,6 +2555,7 @@ public class BassClientStateMachine extends StateMachine {
case REACHED_MAX_SOURCE_LIMIT:
case SWITCH_BCAST_SOURCE:
case PSYNC_ACTIVE_TIMEOUT:
+ case INITIATE_PA_SYNC_TRANSFER:
log(
"defer the message: "
+ messageWhatToString(message.what)
@@ -2646,6 +2663,8 @@ public class BassClientStateMachine extends StateMachine {
return "CONNECT_TIMEOUT";
case CANCEL_PENDING_SOURCE_OPERATION:
return "CANCEL_PENDING_SOURCE_OPERATION";
+ case INITIATE_PA_SYNC_TRANSFER:
+ return "INITIATE_PA_SYNC_TRANSFER";
default:
break;
}
diff --git a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java
index 9b926f1306..8520bc371f 100644
--- a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java
+++ b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java
@@ -1041,6 +1041,23 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
return false;
}
+ @GuardedBy("mLock")
+ private boolean areSameGroupMembers(BluetoothDevice firstDevice, BluetoothDevice secondDevice) {
+
+ if (!Flags.admFixDisconnectOfSetMember()) {
+ /* This function shall return false without the fix flag. */
+ return false;
+ }
+
+ final LeAudioService leAudioService = mFactory.getLeAudioService();
+ if (leAudioService == null) {
+ Log.e(TAG, "LeAudioService not available");
+ return false;
+ }
+
+ return leAudioService.getGroupId(firstDevice) == leAudioService.getGroupId(secondDevice);
+ }
+
/**
* TODO: This method can return true when a fallback device for an unrelated profile is found.
* Take disconnected profile as an argument, and find the exact fallback device. Also, split
@@ -1083,6 +1100,13 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
setLeAudioActiveDevice(null, hasFallbackDevice);
} else {
Log.d(TAG, "Found a LE hearing aid fallback device: " + device);
+ if (areSameGroupMembers(recentlyRemovedDevice, device)) {
+ Log.d(
+ TAG,
+ "Do nothing, removed device belong to the same group as the"
+ + " fallback device.");
+ return true;
+ }
setLeHearingAidActiveDevice(device);
setHearingAidActiveDevice(null, hasFallbackDevice);
setA2dpActiveDevice(null, hasFallbackDevice);
@@ -1152,6 +1176,14 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
setHearingAidActiveDevice(null, true);
} else {
Log.d(TAG, "Found a LE audio fallback device: " + device);
+ if (areSameGroupMembers(recentlyRemovedDevice, device)) {
+ Log.d(
+ TAG,
+ "Do nothing, removed device belong to the same group as the fallback"
+ + " device.");
+ return true;
+ }
+
if (!setLeAudioActiveDevice(device)) {
return false;
}
@@ -1181,6 +1213,14 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
setHearingAidActiveDevice(null, true);
} else {
Log.d(TAG, "Found a LE audio fallback device: " + device);
+ if (areSameGroupMembers(recentlyRemovedDevice, device)) {
+ Log.d(
+ TAG,
+ "Do nothing, removed device belong to the same group as the fallback"
+ + " device.");
+ return true;
+ }
+
setLeAudioActiveDevice(device);
if (!Utils.isDualModeAudioEnabled()) {
setA2dpActiveDevice(null, true);
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java
index 42191c742c..43752e6faf 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java
@@ -531,7 +531,7 @@ class AdapterProperties {
return;
}
- if (Flags.cleanupLeOnlyDeviceType() && deviceType != BluetoothDevice.DEVICE_TYPE_LE) {
+ if (deviceType != BluetoothDevice.DEVICE_TYPE_LE) {
return;
}
@@ -547,12 +547,8 @@ class AdapterProperties {
boolean removeExisting = false;
if (identityAddress.equals(existingIdentityAddress)
&& !address.equals(existingAddress)) {
- if (Flags.cleanupLeOnlyDeviceType()) {
- // Existing device record should be removed only if the device type is LE-only
- removeExisting = (existingDeviceType == BluetoothDevice.DEVICE_TYPE_LE);
- } else {
- removeExisting = true;
- }
+ // Existing device record should be removed only if the device type is LE-only
+ removeExisting = (existingDeviceType == BluetoothDevice.DEVICE_TYPE_LE);
}
if (removeExisting) {
diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
index c48e8b8e3c..bd64fb6c7b 100644
--- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
+++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
@@ -42,8 +42,6 @@ import android.os.ParcelUuid;
import android.os.SystemProperties;
import android.util.Log;
-import androidx.annotation.NonNull;
-
import com.android.bluetooth.BluetoothStatsLog;
import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
@@ -290,10 +288,16 @@ public class RemoteDevices {
@VisibleForTesting
DeviceProperties addDeviceProperties(byte[] address) {
synchronized (mDevices) {
+ String key = Utils.getAddressStringFromByte(address);
+ if (Flags.fixAddDeviceProperties() && mDevices.containsKey(key)) {
+ debugLog("Properties for device " + key + " are already added");
+ return mDevices.get(key);
+ }
+
DeviceProperties prop = new DeviceProperties();
prop.setDevice(mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address)));
prop.setAddress(address);
- String key = Utils.getAddressStringFromByte(address);
+
DeviceProperties pv = mDevices.put(key, prop);
if (pv == null) {
@@ -1315,7 +1319,6 @@ public class RemoteDevices {
mAdapterService.aclStateChangeBroadcastCallback(connectionChangeConsumer);
}
- @NonNull
private void sendPairingCancelIntent(BluetoothDevice device) {
Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_CANCEL);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
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 c93e10febd..0683607ef5 100644
--- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
@@ -117,6 +117,9 @@ public class LeAudioService extends ProfileService {
// Timeout for state machine thread join, to prevent potential ANR.
private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000;
+ /* 5 seconds timeout for Broadcast streaming state transition */
+ private static final int CREATE_BROADCAST_TIMEOUT_MS = 5000;
+
private static LeAudioService sLeAudioService;
/** Indicates group audio support for none direction */
@@ -151,9 +154,6 @@ public class LeAudioService extends ProfileService {
.setSampleRate(BluetoothLeAudioCodecConfig.SAMPLE_RATE_48000)
.build();
- /* 5 seconds timeout for Broadcast streaming state transition */
- private static final int DIALING_OUT_TIMEOUT_MS = 5000;
-
private AdapterService mAdapterService;
private DatabaseManager mDatabaseManager;
private HandlerThread mStateMachinesThread;
@@ -165,6 +165,8 @@ public class LeAudioService extends ProfileService {
private final ReentrantReadWriteLock mGroupReadWriteLock = new ReentrantReadWriteLock();
private final Lock mGroupReadLock = mGroupReadWriteLock.readLock();
private final Lock mGroupWriteLock = mGroupReadWriteLock.writeLock();
+ private CreateBroadcastTimeoutEvent mCreateBroadcastTimeoutEvent;
+
ServiceFactory mServiceFactory = new ServiceFactory();
private final LeAudioNativeInterface mNativeInterface;
@@ -182,7 +184,6 @@ public class LeAudioService extends ProfileService {
BluetoothDevice mLeAudioDeviceInactivatedForHfpHandover = null;
LeAudioBroadcasterNativeInterface mLeAudioBroadcasterNativeInterface = null;
- private DialingOutTimeoutEvent mDialingOutTimeoutEvent = null;
@VisibleForTesting AudioManager mAudioManager;
LeAudioTmapGattServer mTmapGattServer;
int mTmapRoleMask;
@@ -653,7 +654,7 @@ public class LeAudioService extends ProfileService {
mIsSinkStreamMonitorModeEnabled = false;
mIsBroadcastPausedFromOutside = false;
- clearBroadcastTimeoutCallback();
+ clearCreateBroadcastTimeoutCallback();
if (!Flags.leaudioSynchronizeStart()) {
mHandler.removeCallbacks(this::init);
@@ -1148,29 +1149,48 @@ public class LeAudioService extends ProfileService {
return LE_AUDIO_GROUP_ID_INVALID;
}
- /**
- * Creates LeAudio Broadcast instance with BluetoothLeBroadcastSettings.
- *
- * @param broadcastSettings broadcast settings for this broadcast source
- */
- public void createBroadcast(BluetoothLeBroadcastSettings broadcastSettings) {
+ private int canBroadcastBeCreated(BluetoothLeBroadcastSettings broadcastSettings) {
if (mBroadcastDescriptors.size() >= getMaximumNumberOfBroadcasts()) {
Log.w(
TAG,
"createBroadcast reached maximum allowed broadcasts number: "
+ getMaximumNumberOfBroadcasts());
- mHandler.post(
- () ->
- notifyBroadcastStartFailed(
- BluetoothStatusCodes.ERROR_LOCAL_NOT_ENOUGH_RESOURCES));
- return;
+ return BluetoothStatusCodes.ERROR_LOCAL_NOT_ENOUGH_RESOURCES;
+ }
+
+ byte[] broadcastCode = broadcastSettings.getBroadcastCode();
+ if (broadcastCode != null && ((broadcastCode.length > 16) || (broadcastCode.length < 4))) {
+ Log.e(TAG, "Invalid broadcast code length. Should be from 4 to 16 octets long.");
+ return BluetoothStatusCodes.ERROR_LE_BROADCAST_INVALID_CODE;
+ }
+
+ List<BluetoothLeBroadcastSubgroupSettings> settingsList =
+ broadcastSettings.getSubgroupSettings();
+ if (settingsList == null || settingsList.size() < 1) {
+ Log.d(TAG, "subgroup settings is not valid value");
+ return BluetoothStatusCodes.ERROR_BAD_PARAMETERS;
}
+ return BluetoothStatusCodes.SUCCESS;
+ }
+
+ /**
+ * Creates LeAudio Broadcast instance with BluetoothLeBroadcastSettings.
+ *
+ * @param broadcastSettings broadcast settings for this broadcast source
+ */
+ public void createBroadcast(BluetoothLeBroadcastSettings broadcastSettings) {
if (mLeAudioBroadcasterNativeInterface == null) {
Log.w(TAG, "Native interface not available.");
return;
}
+ int canBroadcastBeCreatedReturnCode = canBroadcastBeCreated(broadcastSettings);
+ if (canBroadcastBeCreatedReturnCode != BluetoothStatusCodes.SUCCESS) {
+ mHandler.post(() -> notifyBroadcastStartFailed(canBroadcastBeCreatedReturnCode));
+ return;
+ }
+
if (mAwaitingBroadcastCreateResponse) {
mCreateBroadcastQueue.add(broadcastSettings);
Log.i(TAG, "Broadcast creation queued due to waiting for a previous request response.");
@@ -1192,21 +1212,6 @@ public class LeAudioService extends ProfileService {
}
}
- byte[] broadcastCode = broadcastSettings.getBroadcastCode();
- boolean isEncrypted = (broadcastCode != null) && (broadcastCode.length != 0);
- if (isEncrypted) {
- if ((broadcastCode.length > 16) || (broadcastCode.length < 4)) {
- Log.e(TAG, "Invalid broadcast code length. Should be from 4 to 16 octets long.");
- return;
- }
- }
-
- List<BluetoothLeBroadcastSubgroupSettings> settingsList =
- broadcastSettings.getSubgroupSettings();
- if (settingsList == null || settingsList.size() < 1) {
- Log.d(TAG, "subgroup settings is not valid value");
- return;
- }
mBroadcastSessionStats.put(
INVALID_BROADCAST_ID,
new LeAudioBroadcastSessionStats(broadcastSettings, SystemClock.elapsedRealtime()));
@@ -1214,19 +1219,37 @@ public class LeAudioService extends ProfileService {
BluetoothLeAudioContentMetadata publicMetadata =
broadcastSettings.getPublicBroadcastMetadata();
- Log.i(TAG, "createBroadcast: isEncrypted=" + (isEncrypted ? "true" : "false"));
+ byte[] broadcastCode = broadcastSettings.getBroadcastCode();
+ Log.i(
+ TAG,
+ "createBroadcast: isEncrypted="
+ + (((broadcastCode != null) && (broadcastCode.length != 0))
+ ? "true"
+ : "false"));
mAwaitingBroadcastCreateResponse = true;
if (leaudioBigDependsOnAudioState()) {
mCreateBroadcastQueue.add(broadcastSettings);
}
+
+ if (leaudioBigDependsOnAudioState()) {
+ /* Start timeout to recover from stucked/error create Broadcast operation */
+ if (mCreateBroadcastTimeoutEvent != null) {
+ Log.w(TAG, "CreateBroadcastTimeoutEvent already scheduled");
+ } else {
+ mCreateBroadcastTimeoutEvent = new CreateBroadcastTimeoutEvent();
+ mHandler.postDelayed(mCreateBroadcastTimeoutEvent, CREATE_BROADCAST_TIMEOUT_MS);
+ }
+ }
+
mLeAudioBroadcasterNativeInterface.createBroadcast(
broadcastSettings.isPublicBroadcast(),
broadcastSettings.getBroadcastName(),
broadcastCode,
publicMetadata == null ? null : publicMetadata.getRawMetadata(),
- getBroadcastAudioQualityPerSinkCapabilities(settingsList),
- settingsList.stream()
+ getBroadcastAudioQualityPerSinkCapabilities(
+ broadcastSettings.getSubgroupSettings()),
+ broadcastSettings.getSubgroupSettings().stream()
.map(s -> s.getContentMetadata().getRawMetadata())
.toArray(byte[][]::new));
}
@@ -1280,8 +1303,8 @@ public class LeAudioService extends ProfileService {
Log.d(TAG, "startBroadcast");
/* Start timeout to recover from stucked/error start Broadcast operation */
- mDialingOutTimeoutEvent = new DialingOutTimeoutEvent(broadcastId);
- mHandler.postDelayed(mDialingOutTimeoutEvent, DIALING_OUT_TIMEOUT_MS);
+ mCreateBroadcastTimeoutEvent = new CreateBroadcastTimeoutEvent(broadcastId);
+ mHandler.postDelayed(mCreateBroadcastTimeoutEvent, CREATE_BROADCAST_TIMEOUT_MS);
mLeAudioBroadcasterNativeInterface.startBroadcast(broadcastId);
}
@@ -3181,19 +3204,19 @@ public class LeAudioService extends ProfileService {
setActiveDevice(unicastDevice);
}
- void clearBroadcastTimeoutCallback() {
+ private void clearCreateBroadcastTimeoutCallback() {
if (mHandler == null) {
Log.e(TAG, "No callback handler");
return;
}
/* Timeout callback already cleared */
- if (mDialingOutTimeoutEvent == null) {
+ if (mCreateBroadcastTimeoutEvent == null) {
return;
}
- mHandler.removeCallbacks(mDialingOutTimeoutEvent);
- mDialingOutTimeoutEvent = null;
+ mHandler.removeCallbacks(mCreateBroadcastTimeoutEvent);
+ mCreateBroadcastTimeoutEvent = null;
}
void notifyAudioFrameworkForCodecConfigUpdate(
@@ -3669,7 +3692,10 @@ public class LeAudioService extends ProfileService {
if (!leaudioUseAudioModeListener()) {
mQueuedInCallValue = Optional.empty();
}
- startBroadcast(mBroadcastIdDeactivatedForUnicastTransition.get());
+ if (!leaudioBigDependsOnAudioState()) {
+ startBroadcast(
+ mBroadcastIdDeactivatedForUnicastTransition.get());
+ }
mBroadcastIdDeactivatedForUnicastTransition = Optional.empty();
}
@@ -3729,9 +3755,10 @@ public class LeAudioService extends ProfileService {
mBroadcastSessionStats.put(broadcastId, sessionStats);
}
- // Start sending the actual stream
- startBroadcast(broadcastId);
-
+ if (!leaudioBigDependsOnAudioState()) {
+ // Start sending the actual stream
+ startBroadcast(broadcastId);
+ }
} else {
// TODO: Improve reason reporting or extend the native stack event with reason code
Log.e(
@@ -3744,7 +3771,9 @@ public class LeAudioService extends ProfileService {
if ((mUnicastGroupIdDeactivatedForBroadcastTransition != LE_AUDIO_GROUP_ID_INVALID)
&& mCreateBroadcastQueue.isEmpty()
&& (!Objects.equals(device, mActiveBroadcastAudioDevice))) {
- clearBroadcastTimeoutCallback();
+ if (!leaudioBigDependsOnAudioState()) {
+ clearCreateBroadcastTimeoutCallback();
+ }
updateBroadcastActiveDevice(null, mActiveBroadcastAudioDevice, false);
}
@@ -3755,6 +3784,9 @@ public class LeAudioService extends ProfileService {
.BROADCAST_AUDIO_SESSION_REPORTED__SESSION_SETUP_STATUS__SETUP_STATUS_CREATE_FAILED);
}
+ if (leaudioBigDependsOnAudioState()) {
+ clearCreateBroadcastTimeoutCallback();
+ }
mAwaitingBroadcastCreateResponse = false;
// In case if there were additional calls to create broadcast
@@ -3883,7 +3915,9 @@ public class LeAudioService extends ProfileService {
sessionStats.updateSessionStreamingTime(SystemClock.elapsedRealtime());
}
- clearBroadcastTimeoutCallback();
+ if (!leaudioBigDependsOnAudioState()) {
+ clearCreateBroadcastTimeoutCallback();
+ }
if (previousState == LeAudioStackEvent.BROADCAST_STATE_PAUSED) {
if (bassClientService != null) {
@@ -5279,45 +5313,64 @@ public class LeAudioService extends ProfileService {
return audioFrameworkCalls;
}
- class DialingOutTimeoutEvent implements Runnable {
+ private class CreateBroadcastTimeoutEvent implements Runnable {
Integer mBroadcastId;
- DialingOutTimeoutEvent(Integer broadcastId) {
+ CreateBroadcastTimeoutEvent() {}
+
+ CreateBroadcastTimeoutEvent(Integer broadcastId) {
mBroadcastId = broadcastId;
}
@Override
public void run() {
- Log.w(TAG, "Failed to start Broadcast in time: " + mBroadcastId);
-
- mDialingOutTimeoutEvent = null;
+ if (leaudioBigDependsOnAudioState()) {
+ Log.w(TAG, "Failed to start Broadcast in time");
- if (getLeAudioService() == null) {
- Log.e(TAG, "DialingOutTimeoutEvent: No LE Audio service");
- return;
- }
+ if (getLeAudioService() == null) {
+ Log.e(TAG, "CreateBroadcastTimeoutEvent: No LE Audio service");
+ return;
+ }
- if (Flags.leaudioBroadcastDestroyAfterTimeout()) {
- LeAudioBroadcastSessionStats sessionStats =
- mBroadcastSessionStats.get(mBroadcastId);
- if (sessionStats != null) {
- sessionStats.updateSessionStatus(
- BluetoothStatsLog
- .BROADCAST_AUDIO_SESSION_REPORTED__SESSION_SETUP_STATUS__SETUP_STATUS_STREAMING_FAILED);
- // log once destroyed
+ if (sLeAudioService.mHandler == null) {
+ Log.w(TAG, "CreateBroadcastTimeoutEvent: No handler");
+ return;
}
- transitionFromBroadcastToUnicast();
- destroyBroadcast(mBroadcastId);
+
+ mHandler.post(() -> notifyBroadcastStartFailed(BluetoothStatusCodes.ERROR_TIMEOUT));
} else {
- if (mActiveBroadcastAudioDevice != null) {
- updateBroadcastActiveDevice(null, mActiveBroadcastAudioDevice, false);
+ Log.w(TAG, "Failed to start Broadcast in time: " + mBroadcastId);
+
+ mCreateBroadcastTimeoutEvent = null;
+
+ if (getLeAudioService() == null) {
+ Log.e(TAG, "CreateBroadcastTimeoutEvent: No LE Audio service");
+ return;
}
- mHandler.post(() -> notifyBroadcastStartFailed(BluetoothStatusCodes.ERROR_TIMEOUT));
- logBroadcastSessionStatsWithStatus(
- mBroadcastId,
- BluetoothStatsLog
- .BROADCAST_AUDIO_SESSION_REPORTED__SESSION_SETUP_STATUS__SETUP_STATUS_STREAMING_FAILED);
+ if (Flags.leaudioBroadcastDestroyAfterTimeout()) {
+ LeAudioBroadcastSessionStats sessionStats =
+ mBroadcastSessionStats.get(mBroadcastId);
+ if (sessionStats != null) {
+ sessionStats.updateSessionStatus(
+ BluetoothStatsLog
+ .BROADCAST_AUDIO_SESSION_REPORTED__SESSION_SETUP_STATUS__SETUP_STATUS_STREAMING_FAILED);
+ // log once destroyed
+ }
+ transitionFromBroadcastToUnicast();
+ destroyBroadcast(mBroadcastId);
+ } else {
+ if (mActiveBroadcastAudioDevice != null) {
+ updateBroadcastActiveDevice(null, mActiveBroadcastAudioDevice, false);
+ }
+
+ mHandler.post(
+ () -> notifyBroadcastStartFailed(BluetoothStatusCodes.ERROR_TIMEOUT));
+ logBroadcastSessionStatsWithStatus(
+ mBroadcastId,
+ BluetoothStatsLog
+ .BROADCAST_AUDIO_SESSION_REPORTED__SESSION_SETUP_STATUS__SETUP_STATUS_STREAMING_FAILED);
+ }
}
}
}
diff --git a/android/app/src/com/android/bluetooth/le_scan/MsftAdvMonitor.java b/android/app/src/com/android/bluetooth/le_scan/MsftAdvMonitor.java
index acf80cfd76..657ea4d5a9 100644
--- a/android/app/src/com/android/bluetooth/le_scan/MsftAdvMonitor.java
+++ b/android/app/src/com/android/bluetooth/le_scan/MsftAdvMonitor.java
@@ -70,7 +70,7 @@ class MsftAdvMonitor {
mMonitor.rssi_sampling_period = RSSI_SAMPLING_PERIOD;
mMonitor.condition_type = MSFT_CONDITION_TYPE_PATTERNS;
- if (filter.getServiceDataUuid() != null && filter.getServiceDataMask() == null) {
+ if (filter.getServiceDataUuid() != null && dataMaskIsEmpty(filter.getServiceDataMask())) {
Pattern pattern = new Pattern();
pattern.ad_type = (byte) 0x16; // Bluetooth Core Spec Part A, Section 1
pattern.start_byte = FILTER_PATTERN_START_POSITION;
@@ -86,8 +86,7 @@ class MsftAdvMonitor {
mPatterns.add(pattern);
} else if (filter.getAdvertisingData() != null
&& filter.getAdvertisingData().length != 0
- && (filter.getAdvertisingDataMask() == null
- || filter.getAdvertisingDataMask().length == 0)) {
+ && dataMaskIsEmpty(filter.getAdvertisingDataMask())) {
Pattern pattern = new Pattern();
pattern.ad_type = (byte) filter.getAdvertisingDataType();
pattern.start_byte = FILTER_PATTERN_START_POSITION;
@@ -112,4 +111,10 @@ class MsftAdvMonitor {
Address getAddress() {
return mAddress;
}
+
+ private boolean dataMaskIsEmpty(byte[] mask) {
+ if (mask == null || mask.length == 0) return true;
+ if (mask.length == 1 && mask[0] == 0) return true;
+ return false;
+ }
}
diff --git a/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java b/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java
index 573b4f49d2..09f3626ad7 100644
--- a/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java
+++ b/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java
@@ -463,12 +463,7 @@ public class TransitionalScanHelper {
}
} catch (RemoteException | PendingIntent.CanceledException e) {
Log.e(TAG, "Exception: " + e);
- if (Flags.leScanFixRemoteException()) {
- handleDeadScanClient(client);
- } else {
- mScannerMap.remove(client.scannerId);
- mScanManager.stopScan(client.scannerId);
- }
+ handleDeadScanClient(client);
}
}
}
@@ -772,12 +767,7 @@ public class TransitionalScanHelper {
}
} catch (RemoteException | PendingIntent.CanceledException e) {
Log.e(TAG, "Exception: " + e);
- if (Flags.leScanFixRemoteException()) {
- handleDeadScanClient(client);
- } else {
- mScannerMap.remove(client.scannerId);
- mScanManager.stopScan(client.scannerId);
- }
+ handleDeadScanClient(client);
}
}
@@ -1518,15 +1508,7 @@ public class TransitionalScanHelper {
ScanClient client = getScanClient(mScannerId);
if (client != null) {
- if (Flags.leScanFixRemoteException()) {
- handleDeadScanClient(client);
- } else {
- client.appDied = true;
- if (client.stats != null) {
- client.stats.isAppDead = true;
- }
- stopScanInternal(client.scannerId);
- }
+ handleDeadScanClient(client);
}
}
diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
index f70903f1be..e0fce72338 100644
--- a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
+++ b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
@@ -3352,6 +3352,7 @@ public class BluetoothMapContentObserver {
return handle;
}
+ @SuppressWarnings("EnumOrdinal") // remove entire usage of internal intent
public long sendMmsMessage(
String folder,
String[] toAddress,
@@ -4090,6 +4091,7 @@ public class BluetoothMapContentObserver {
}
}
+ @SuppressWarnings("EnumOrdinal") // remove entire usage of internal intent
public static void actionMessageSentDisconnected(Context context, Intent intent, int result) {
TYPE type =
TYPE.fromOrdinal(
@@ -4277,6 +4279,7 @@ public class BluetoothMapContentObserver {
}
}
+ @SuppressWarnings("EnumOrdinal") // remove entire usage of internal intent
public boolean handleSmsSendIntent(Context context, Intent intent) {
TYPE type =
TYPE.fromOrdinal(
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java
index 87145b17d0..8cbd32cfba 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppNotification.java
@@ -141,7 +141,7 @@ class BluetoothOppNotification {
private final HashMap<String, NotificationItem> mNotifications = new HashMap<>();
- private NotificationUpdateThread mUpdateNotificationThread;
+ @VisibleForTesting NotificationUpdateThread mUpdateNotificationThread;
private int mPendingUpdate = 0;
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java
index 559654de4f..a8c653db5c 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java
@@ -135,7 +135,7 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti
private BluetoothShareContentObserver mObserver;
/** Class to handle Notification Manager updates */
- private BluetoothOppNotification mNotifier;
+ @VisibleForTesting BluetoothOppNotification mNotifier;
private boolean mPendingUpdate;
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java
index b66295d43e..5565fbd87d 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java
@@ -280,6 +280,7 @@ public class BluetoothPbapCallLogComposer implements AutoCloseable {
}
/** Closes the composer, releasing all of its resources. */
+ @Override
public void close() {
if (mCursor != null) {
try {
diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java
index ac65f6c78e..8f894848dd 100644
--- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java
+++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java
@@ -194,6 +194,7 @@ public class BluetoothPbapSimVcardManager implements AutoCloseable {
}
/** Closes the manager, releasing all of its resources. */
+ @Override
public void close() {
if (mCursor != null) {
try {
diff --git a/android/app/src/com/android/bluetooth/tbs/TbsGatt.java b/android/app/src/com/android/bluetooth/tbs/TbsGatt.java
index af1cc02291..803b249a3d 100644
--- a/android/app/src/com/android/bluetooth/tbs/TbsGatt.java
+++ b/android/app/src/com/android/bluetooth/tbs/TbsGatt.java
@@ -1036,6 +1036,7 @@ public class TbsGatt {
return mTbsService.getDeviceAuthorization(device);
}
+ @SuppressWarnings("EnumOrdinal")
private void onRejectedAuthorizationGattOperation(BluetoothDevice device, GattOpContext op) {
UUID charUuid =
(op.mCharacteristic != null
@@ -1102,7 +1103,7 @@ public class TbsGatt {
boolean allowToReadRealValue = false;
byte[] buffer = null;
- /* Allow only some informations to be disclosed at this stage. */
+ /* Allow only some information to be disclosed at this stage. */
if (charUuid.equals(UUID_BEARER_PROVIDER_NAME)) {
ByteBuffer bb = ByteBuffer.allocate(0).order(ByteOrder.LITTLE_ENDIAN);
bb.put("".getBytes());
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
index 5ebd46026b..99f296b9be 100644
--- a/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlService.java
@@ -19,6 +19,14 @@ package com.android.bluetooth.vc;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.Manifest.permission.BLUETOOTH_PRIVILEGED;
+import static android.bluetooth.BluetoothDevice.BOND_BONDED;
+import static android.bluetooth.BluetoothDevice.BOND_NONE;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTING;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
import static java.util.Objects.requireNonNull;
@@ -31,7 +39,6 @@ import android.bluetooth.IBluetoothLeAudio;
import android.bluetooth.IBluetoothVolumeControl;
import android.bluetooth.IBluetoothVolumeControlCallback;
import android.content.AttributionSource;
-import android.content.Context;
import android.media.AudioManager;
import android.os.Handler;
import android.os.HandlerThread;
@@ -70,27 +77,28 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class VolumeControlService extends ProfileService {
- private static final String TAG = "VolumeControlService";
+ private static final String TAG = VolumeControlService.class.getSimpleName();
- // Timeout for state machine thread join, to prevent potential ANR.
private static final int SM_THREAD_JOIN_TIMEOUT_MS = 1000;
-
private static final int LE_AUDIO_MAX_VOL = 255;
+ /* As defined by Volume Control Service 1.0.1, 3.3.1. Volume Flags behavior.
+ * User Set Volume Setting means that remote keeps volume in its cache. */
+ @VisibleForTesting static final int VOLUME_FLAGS_PERSISTED_USER_SET_VOLUME_MASK = 0x01;
private static VolumeControlService sVolumeControlService;
- private AdapterService mAdapterService;
- private DatabaseManager mDatabaseManager;
- private HandlerThread mStateMachinesThread;
- private Handler mHandler = null;
-
@VisibleForTesting
@GuardedBy("mCallbacks")
final RemoteCallbackList<IBluetoothVolumeControlCallback> mCallbacks =
new RemoteCallbackList<>();
- VolumeControlNativeInterface mVolumeControlNativeInterface;
- @VisibleForTesting AudioManager mAudioManager;
+ private final AdapterService mAdapterService;
+ private final AudioManager mAudioManager;
+ private final DatabaseManager mDatabaseManager;
+ private final Handler mHandler;
+ private final HandlerThread mStateMachinesThread;
+ private final Looper mStateMachinesLooper;
+ private final VolumeControlNativeInterface mNativeInterface;
private final Map<BluetoothDevice, VolumeControlStateMachine> mStateMachines = new HashMap<>();
private final Map<BluetoothDevice, VolumeControlOffsetDescriptor> mAudioOffsets =
@@ -100,15 +108,34 @@ public class VolumeControlService extends ProfileService {
private final Map<Integer, Boolean> mGroupMuteCache = new HashMap<>();
private final Map<BluetoothDevice, Integer> mDeviceVolumeCache = new HashMap<>();
- /* As defined by Volume Control Service 1.0.1, 3.3.1. Volume Flags behavior.
- * User Set Volume Setting means that remote keeps volume in its cache.
- */
- @VisibleForTesting static final int VOLUME_FLAGS_PERSISTED_USER_SET_VOLUME_MASK = 0x01;
-
@VisibleForTesting ServiceFactory mFactory = new ServiceFactory();
- public VolumeControlService(Context ctx) {
- super(ctx);
+ public VolumeControlService(AdapterService adapterService) {
+ this(adapterService, null, VolumeControlNativeInterface.getInstance());
+ }
+
+ @VisibleForTesting
+ VolumeControlService(
+ AdapterService adapterService,
+ Looper looper,
+ VolumeControlNativeInterface nativeInterface) {
+ super(requireNonNull(adapterService));
+ mAdapterService = adapterService;
+ mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
+ mNativeInterface = requireNonNull(nativeInterface);
+ mAudioManager = requireNonNull(getSystemService(AudioManager.class));
+ if (looper == null) {
+ mHandler = new Handler(requireNonNull(Looper.getMainLooper()));
+ mStateMachinesThread = new HandlerThread("VolumeControlService.StateMachines");
+ mStateMachinesThread.start();
+ mStateMachinesLooper = mStateMachinesThread.getLooper();
+ } else {
+ mHandler = new Handler(looper);
+ mStateMachinesThread = null;
+ mStateMachinesLooper = looper;
+ }
+ setVolumeControlService(this);
+ mNativeInterface.init();
}
public static boolean isEnabled() {
@@ -121,44 +148,8 @@ public class VolumeControlService extends ProfileService {
}
@Override
- public void start() {
- Log.d(TAG, "start()");
- if (sVolumeControlService != null) {
- throw new IllegalStateException("start() called twice");
- }
-
- // Get AdapterService, VolumeControlNativeInterface, DatabaseManager, AudioManager.
- // None of them can be null.
- mAdapterService = requireNonNull(AdapterService.getAdapterService());
- mDatabaseManager = requireNonNull(mAdapterService.getDatabase());
- mVolumeControlNativeInterface = requireNonNull(VolumeControlNativeInterface.getInstance());
- mAudioManager = requireNonNull(getSystemService(AudioManager.class));
-
- // Start handler thread for state machines
- mHandler = new Handler(Looper.getMainLooper());
- mStateMachines.clear();
- mStateMachinesThread = new HandlerThread("VolumeControlService.StateMachines");
- mStateMachinesThread.start();
-
- mAudioOffsets.clear();
- mGroupVolumeCache.clear();
- mGroupMuteCache.clear();
- mDeviceVolumeCache.clear();
-
- // Mark service as started
- setVolumeControlService(this);
-
- // Initialize native interface
- mVolumeControlNativeInterface.init();
- }
-
- @Override
public void stop() {
Log.d(TAG, "stop()");
- if (sVolumeControlService == null) {
- Log.w(TAG, "stop() called before start()");
- return;
- }
// Mark service as stopped
setVolumeControlService(null);
@@ -167,7 +158,6 @@ public class VolumeControlService extends ProfileService {
synchronized (mStateMachines) {
for (VolumeControlStateMachine sm : mStateMachines.values()) {
sm.doQuit();
- sm.cleanup();
}
mStateMachines.clear();
}
@@ -176,44 +166,26 @@ public class VolumeControlService extends ProfileService {
try {
mStateMachinesThread.quitSafely();
mStateMachinesThread.join(SM_THREAD_JOIN_TIMEOUT_MS);
- mStateMachinesThread = null;
} catch (InterruptedException e) {
// Do not rethrow as we are shutting down anyway
}
}
- // Unregister handler and remove all queued messages.
- if (mHandler != null) {
- mHandler.removeCallbacksAndMessages(null);
- mHandler = null;
- }
+ mHandler.removeCallbacksAndMessages(null);
// Cleanup native interface
- mVolumeControlNativeInterface.cleanup();
- mVolumeControlNativeInterface = null;
+ mNativeInterface.cleanup();
mAudioOffsets.clear();
mGroupVolumeCache.clear();
mGroupMuteCache.clear();
mDeviceVolumeCache.clear();
- // Clear AdapterService, VolumeControlNativeInterface
- mAudioManager = null;
- mVolumeControlNativeInterface = null;
- mAdapterService = null;
-
synchronized (mCallbacks) {
- if (mCallbacks != null) {
- mCallbacks.kill();
- }
+ mCallbacks.kill();
}
}
- @Override
- public void cleanup() {
- Log.d(TAG, "cleanup()");
- }
-
/**
* Get the VolumeControlService instance
*
@@ -244,7 +216,7 @@ public class VolumeControlService extends ProfileService {
return false;
}
- if (getConnectionPolicy(device) == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
+ if (getConnectionPolicy(device) == CONNECTION_POLICY_FORBIDDEN) {
return false;
}
final ParcelUuid[] featureUuids = mAdapterService.getRemoteUuids(device);
@@ -260,7 +232,7 @@ public class VolumeControlService extends ProfileService {
if (smConnect == null) {
Log.e(TAG, "Cannot connect to " + device + " : no state machine");
}
- smConnect.sendMessage(VolumeControlStateMachine.CONNECT);
+ smConnect.sendMessage(VolumeControlStateMachine.MESSAGE_CONNECT);
}
return true;
@@ -274,7 +246,7 @@ public class VolumeControlService extends ProfileService {
synchronized (mStateMachines) {
VolumeControlStateMachine sm = getOrCreateStateMachine(device);
if (sm != null) {
- sm.sendMessage(VolumeControlStateMachine.DISCONNECT);
+ sm.sendMessage(VolumeControlStateMachine.MESSAGE_DISCONNECT);
}
}
@@ -317,11 +289,11 @@ public class VolumeControlService extends ProfileService {
int bondState = mAdapterService.getBondState(device);
// Allow this connection only if the device is bonded. Any attempt to connect while
// bonding would potentially lead to an unauthorized connection.
- if (bondState != BluetoothDevice.BOND_BONDED) {
+ if (bondState != BOND_BONDED) {
Log.w(TAG, "okToConnect: return false, bondState=" + bondState);
return false;
- } else if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_UNKNOWN
- && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+ } else if (connectionPolicy != CONNECTION_POLICY_UNKNOWN
+ && connectionPolicy != CONNECTION_POLICY_ALLOWED) {
// Otherwise, reject the connection if connectionPolicy is not valid.
Log.w(TAG, "okToConnect: return false, connectionPolicy=" + connectionPolicy);
return false;
@@ -344,7 +316,7 @@ public class VolumeControlService extends ProfileService {
if (!Utils.arrayContains(featureUuids, BluetoothUuid.VOLUME_CONTROL)) {
continue;
}
- int connectionState = BluetoothProfile.STATE_DISCONNECTED;
+ int connectionState = STATE_DISCONNECTED;
VolumeControlStateMachine sm = mStateMachines.get(device);
if (sm != null) {
connectionState = sm.getConnectionState();
@@ -380,7 +352,7 @@ public class VolumeControlService extends ProfileService {
synchronized (mStateMachines) {
VolumeControlStateMachine sm = mStateMachines.get(device);
if (sm == null) {
- return BluetoothProfile.STATE_DISCONNECTED;
+ return STATE_DISCONNECTED;
}
return sm.getConnectionState();
}
@@ -404,9 +376,9 @@ public class VolumeControlService extends ProfileService {
Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy);
mDatabaseManager.setProfileConnectionPolicy(
device, BluetoothProfile.VOLUME_CONTROL, connectionPolicy);
- if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
+ if (connectionPolicy == CONNECTION_POLICY_ALLOWED) {
connect(device);
- } else if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
+ } else if (connectionPolicy == CONNECTION_POLICY_FORBIDDEN) {
disconnect(device);
}
return true;
@@ -465,7 +437,7 @@ public class VolumeControlService extends ProfileService {
return;
}
- mVolumeControlNativeInterface.setExtAudioOutVolumeOffset(device, instanceId, volumeOffset);
+ mNativeInterface.setExtAudioOutVolumeOffset(device, instanceId, volumeOffset);
}
void setDeviceVolume(BluetoothDevice device, int volume, boolean isGroupOp) {
@@ -478,18 +450,19 @@ public class VolumeControlService extends ProfileService {
Log.e(TAG, "leAudioService not available");
return;
}
- int groupId = leAudioService.getGroupId(device);
- if (groupId == IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID) {
- Log.e(TAG, "Device not a part of a group");
- return;
- }
if (isGroupOp) {
+ int groupId = leAudioService.getGroupId(device);
+ if (groupId == IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID) {
+ Log.e(TAG, "Device not a part of a group");
+ return;
+ }
+
setGroupVolume(groupId, volume);
} else {
Log.i(TAG, "Setting individual device volume");
mDeviceVolumeCache.put(device, volume);
- mVolumeControlNativeInterface.setVolume(device, volume);
+ mNativeInterface.setVolume(device, volume);
}
}
@@ -500,7 +473,7 @@ public class VolumeControlService extends ProfileService {
}
mGroupVolumeCache.put(groupId, volume);
- mVolumeControlNativeInterface.setGroupVolume(groupId, volume);
+ mNativeInterface.setGroupVolume(groupId, volume);
// We only receive the volume change and mute state needs to be acquired manually
Boolean isGroupMute = mGroupMuteCache.getOrDefault(groupId, false);
@@ -508,7 +481,7 @@ public class VolumeControlService extends ProfileService {
/* Note: AudioService keeps volume levels for each stream and for each device type,
* however it stores the mute state only for the stream type but not for each individual
- * device type. When active device changes, it's volume level gets aplied, but mute state
+ * device type. When active device changes, it's volume level gets applied, but mute state
* is not, but can be either derived from the volume level or just unmuted like for A2DP.
* Also setting volume level > 0 to audio system will implicitly unmute the stream.
* However LeAudio devices can keep their volume level high, while keeping it mute so we
@@ -580,21 +553,21 @@ public class VolumeControlService extends ProfileService {
}
public void mute(BluetoothDevice device) {
- mVolumeControlNativeInterface.mute(device);
+ mNativeInterface.mute(device);
}
public void muteGroup(int groupId) {
mGroupMuteCache.put(groupId, true);
- mVolumeControlNativeInterface.muteGroup(groupId);
+ mNativeInterface.muteGroup(groupId);
}
public void unmute(BluetoothDevice device) {
- mVolumeControlNativeInterface.unmute(device);
+ mNativeInterface.unmute(device);
}
public void unmuteGroup(int groupId) {
mGroupMuteCache.put(groupId, false);
- mVolumeControlNativeInterface.unmuteGroup(groupId);
+ mNativeInterface.unmuteGroup(groupId);
}
void notifyNewCallbackOfKnownVolumeInfo(IBluetoothVolumeControlCallback callback) {
@@ -670,7 +643,7 @@ public class VolumeControlService extends ProfileService {
if (sm == null) {
return;
}
- if (sm.getConnectionState() != BluetoothProfile.STATE_CONNECTED) {
+ if (sm.getConnectionState() != STATE_CONNECTED) {
return;
}
}
@@ -680,7 +653,7 @@ public class VolumeControlService extends ProfileService {
synchronized (mStateMachines) {
VolumeControlStateMachine sm = mStateMachines.get(device);
if (sm != null) {
- can_change_volume = (sm.getConnectionState() == BluetoothProfile.STATE_CONNECTED);
+ can_change_volume = (sm.getConnectionState() == STATE_CONNECTED);
}
}
@@ -691,15 +664,15 @@ public class VolumeControlService extends ProfileService {
groupId, IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME);
if (groupVolume != IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME) {
Log.i(TAG, "Setting value:" + groupVolume + " to " + device);
- mVolumeControlNativeInterface.setVolume(device, groupVolume);
+ mNativeInterface.setVolume(device, groupVolume);
}
Boolean isGroupMuted = mGroupMuteCache.getOrDefault(groupId, false);
Log.i(TAG, "Setting mute:" + isGroupMuted + " to " + device);
if (isGroupMuted) {
- mVolumeControlNativeInterface.mute(device);
+ mNativeInterface.mute(device);
} else {
- mVolumeControlNativeInterface.unmute(device);
+ mNativeInterface.unmute(device);
}
}
}
@@ -865,21 +838,20 @@ public class VolumeControlService extends ProfileService {
synchronized (mStateMachines) {
VolumeControlStateMachine sm = mStateMachines.get(device);
if (sm != null) {
- can_change_volume =
- (sm.getConnectionState() == BluetoothProfile.STATE_CONNECTED);
+ can_change_volume = (sm.getConnectionState() == STATE_CONNECTED);
}
}
if (can_change_volume && (groupVolume != volume)) {
Log.i(TAG, "Setting value:" + groupVolume + " to " + device);
- mVolumeControlNativeInterface.setVolume(device, groupVolume);
+ mNativeInterface.setVolume(device, groupVolume);
}
if (can_change_volume && (groupMute != mute)) {
Log.i(TAG, "Setting mute:" + groupMute + " to " + device);
if (groupMute) {
- mVolumeControlNativeInterface.mute(device);
+ mNativeInterface.mute(device);
} else {
- mVolumeControlNativeInterface.unmute(device);
+ mNativeInterface.unmute(device);
}
}
} else {
@@ -925,19 +897,16 @@ public class VolumeControlService extends ProfileService {
Log.d(TAG, "Volume mode: " + mode + "0: normal, 1: ring, 2,3: call");
- switch (mode) {
- case AudioManager.MODE_IN_COMMUNICATION:
- case AudioManager.MODE_IN_CALL:
- return AudioManager.STREAM_VOICE_CALL;
- case AudioManager.MODE_RINGTONE:
+ return switch (mode) {
+ case AudioManager.MODE_IN_CALL, AudioManager.MODE_IN_COMMUNICATION -> {
+ yield AudioManager.STREAM_VOICE_CALL;
+ }
+ case AudioManager.MODE_RINGTONE -> {
Log.d(TAG, " Update during ringtone applied to voice call");
- return AudioManager.STREAM_VOICE_CALL;
- case AudioManager.MODE_NORMAL:
- default:
- // other conditions will influence the stream type choice, read on...
- break;
- }
- return AudioManager.STREAM_MUSIC;
+ yield AudioManager.STREAM_VOICE_CALL;
+ }
+ default -> AudioManager.STREAM_MUSIC;
+ };
}
void handleExternalOutputs(BluetoothDevice device, int numberOfExternalOutputs) {
@@ -1277,12 +1246,9 @@ public class VolumeControlService extends ProfileService {
if (stackEvent.type
== VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED) {
switch (stackEvent.valueInt1) {
- case VolumeControlStackEvent.CONNECTION_STATE_CONNECTED:
- case VolumeControlStackEvent.CONNECTION_STATE_CONNECTING:
+ case STATE_CONNECTED, STATE_CONNECTING -> {
sm = getOrCreateStateMachine(device);
- break;
- default:
- break;
+ }
}
}
}
@@ -1290,7 +1256,7 @@ public class VolumeControlService extends ProfileService {
Log.e(TAG, "Cannot process stack event: no state machine: " + stackEvent);
return;
}
- sm.sendMessage(VolumeControlStateMachine.STACK_EVENT, stackEvent);
+ sm.sendMessage(VolumeControlStateMachine.MESSAGE_STACK_EVENT, stackEvent);
}
}
@@ -1307,11 +1273,9 @@ public class VolumeControlService extends ProfileService {
Log.d(TAG, "Creating a new state machine for " + device);
sm =
- VolumeControlStateMachine.make(
- device,
- this,
- mVolumeControlNativeInterface,
- mStateMachinesThread.getLooper());
+ new VolumeControlStateMachine(
+ this, device, mNativeInterface, mStateMachinesLooper);
+ sm.start();
mStateMachines.put(device, sm);
return sm;
}
@@ -1392,7 +1356,7 @@ public class VolumeControlService extends ProfileService {
void bondStateChanged(BluetoothDevice device, int bondState) {
Log.d(TAG, "Bond state changed for device: " + device + " state: " + bondState);
// Remove state machine if the bonding for a device is removed
- if (bondState != BluetoothDevice.BOND_NONE) {
+ if (bondState != BOND_NONE) {
return;
}
@@ -1401,7 +1365,7 @@ public class VolumeControlService extends ProfileService {
if (sm == null) {
return;
}
- if (sm.getConnectionState() != BluetoothProfile.STATE_DISCONNECTED) {
+ if (sm.getConnectionState() != STATE_DISCONNECTED) {
Log.i(TAG, "Disconnecting device because it was unbonded.");
disconnect(device);
return;
@@ -1421,7 +1385,6 @@ public class VolumeControlService extends ProfileService {
}
Log.i(TAG, "removeStateMachine: removing state machine for device: " + device);
sm.doQuit();
- sm.cleanup();
mStateMachines.remove(device);
}
}
@@ -1450,13 +1413,13 @@ public class VolumeControlService extends ProfileService {
}
// Check if the device is disconnected - if unbond, remove the state machine
- if (toState == BluetoothProfile.STATE_DISCONNECTED) {
+ if (toState == STATE_DISCONNECTED) {
int bondState = mAdapterService.getBondState(device);
- if (bondState == BluetoothDevice.BOND_NONE) {
+ if (bondState == BOND_NONE) {
Log.d(TAG, device + " is unbond. Remove state machine");
removeStateMachine(device);
}
- } else if (toState == BluetoothProfile.STATE_CONNECTED) {
+ } else if (toState == STATE_CONNECTED) {
// Restore the group volume if it was changed while the device was not yet connected.
CsipSetCoordinatorService csipClient = mFactory.getCsipSetCoordinatorService();
if (csipClient != null) {
@@ -1466,14 +1429,14 @@ public class VolumeControlService extends ProfileService {
mGroupVolumeCache.getOrDefault(
groupId, IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME);
if (groupVolume != IBluetoothVolumeControl.VOLUME_CONTROL_UNKNOWN_VOLUME) {
- mVolumeControlNativeInterface.setVolume(device, groupVolume);
+ mNativeInterface.setVolume(device, groupVolume);
}
Boolean groupMute = mGroupMuteCache.getOrDefault(groupId, false);
if (groupMute) {
- mVolumeControlNativeInterface.mute(device);
+ mNativeInterface.mute(device);
} else {
- mVolumeControlNativeInterface.unmute(device);
+ mNativeInterface.unmute(device);
}
}
} else {
@@ -1554,7 +1517,7 @@ public class VolumeControlService extends ProfileService {
VolumeControlService service = getService(source);
if (service == null) {
- return BluetoothProfile.STATE_DISCONNECTED;
+ return STATE_DISCONNECTED;
}
return service.getConnectionState(device);
@@ -1580,7 +1543,7 @@ public class VolumeControlService extends ProfileService {
VolumeControlService service = getService(source);
if (service == null) {
- return BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+ return CONNECTION_POLICY_UNKNOWN;
}
service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null);
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java b/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java
index 62f8b702d7..d102952d27 100644
--- a/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlStackEvent.java
@@ -18,6 +18,7 @@
package com.android.bluetooth.vc;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
public class VolumeControlStackEvent {
// Event types for STACK_EVENT message (coming from native)
@@ -34,13 +35,6 @@ public class VolumeControlStackEvent {
public static final int EVENT_TYPE_EXT_AUDIO_IN_DESCR_CHANGED = 10;
public static final int EVENT_TYPE_EXT_AUDIO_IN_GAIN_PROPS_CHANGED = 11;
- // Do not modify without updating the HAL bt_vc_aid.h files.
- // Match up with enum class ConnectionState of bt_vc_aid.h.
- static final int CONNECTION_STATE_DISCONNECTED = 0;
- static final int CONNECTION_STATE_CONNECTING = 1;
- static final int CONNECTION_STATE_CONNECTED = 2;
- static final int CONNECTION_STATE_DISCONNECTING = 3;
-
public int type;
public BluetoothDevice device;
public int valueInt1;
@@ -108,18 +102,7 @@ public class VolumeControlStackEvent {
private static String eventTypeValue1ToString(int type, int value) {
switch (type) {
case EVENT_TYPE_CONNECTION_STATE_CHANGED:
- switch (value) {
- case CONNECTION_STATE_DISCONNECTED:
- return "CONNECTION_STATE_DISCONNECTED";
- case CONNECTION_STATE_CONNECTING:
- return "CONNECTION_STATE_CONNECTING";
- case CONNECTION_STATE_CONNECTED:
- return "CONNECTION_STATE_CONNECTED";
- case CONNECTION_STATE_DISCONNECTING:
- return "CONNECTION_STATE_DISCONNECTING";
- default:
- return "UNKNOWN";
- }
+ return BluetoothProfile.getConnectionStateName(value);
case EVENT_TYPE_VOLUME_STATE_CHANGED:
return "{group_id:" + value + "}";
case EVENT_TYPE_DEVICE_AVAILABLE:
@@ -143,18 +126,7 @@ public class VolumeControlStackEvent {
private static String eventTypeValue2ToString(int type, int value) {
switch (type) {
case EVENT_TYPE_CONNECTION_STATE_CHANGED:
- switch (value) {
- case CONNECTION_STATE_DISCONNECTED:
- return "CONNECTION_STATE_DISCONNECTED";
- case CONNECTION_STATE_CONNECTING:
- return "CONNECTION_STATE_CONNECTING";
- case CONNECTION_STATE_CONNECTED:
- return "CONNECTION_STATE_CONNECTED";
- case CONNECTION_STATE_DISCONNECTING:
- return "CONNECTION_STATE_DISCONNECTING";
- default:
- return "UNKNOWN";
- }
+ return BluetoothProfile.getConnectionStateName(value);
case EVENT_TYPE_VOLUME_STATE_CHANGED:
return "{volume:" + value + "}";
case EVENT_TYPE_DEVICE_AVAILABLE:
diff --git a/android/app/src/com/android/bluetooth/vc/VolumeControlStateMachine.java b/android/app/src/com/android/bluetooth/vc/VolumeControlStateMachine.java
index 4a68e8f337..1e1ca9aa16 100644
--- a/android/app/src/com/android/bluetooth/vc/VolumeControlStateMachine.java
+++ b/android/app/src/com/android/bluetooth/vc/VolumeControlStateMachine.java
@@ -18,6 +18,11 @@
package com.android.bluetooth.vc;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTING;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING;
+import static android.bluetooth.BluetoothProfile.getConnectionStateName;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
@@ -35,37 +40,34 @@ import com.android.internal.util.StateMachine;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.time.Duration;
import java.util.Scanner;
-public class VolumeControlStateMachine extends StateMachine {
+class VolumeControlStateMachine extends StateMachine {
+ private static final String TAG = VolumeControlStateMachine.class.getSimpleName();
- private static final String TAG = "VolumeControlStateMachine";
+ static final int MESSAGE_CONNECT = 1;
+ static final int MESSAGE_DISCONNECT = 2;
+ static final int MESSAGE_STACK_EVENT = 101;
+ @VisibleForTesting static final int MESSAGE_CONNECT_TIMEOUT = 201;
- static final int CONNECT = 1;
- static final int DISCONNECT = 2;
- @VisibleForTesting static final int STACK_EVENT = 101;
- @VisibleForTesting static final int CONNECT_TIMEOUT = 201;
+ @VisibleForTesting static final Duration CONNECT_TIMEOUT = Duration.ofSeconds(30);
- // NOTE: the value is not "final" - it is modified in the unit tests
- @VisibleForTesting static int sConnectTimeoutMs = 30000; // 30s
+ private final Disconnected mDisconnected;
+ private final Connecting mConnecting;
+ private final Disconnecting mDisconnecting;
+ private final Connected mConnected;
+ private final VolumeControlService mService;
+ private final VolumeControlNativeInterface mNativeInterface;
+ private final BluetoothDevice mDevice;
- private Disconnected mDisconnected;
- private Connecting mConnecting;
- private Disconnecting mDisconnecting;
- private Connected mConnected;
private int mLastConnectionState = -1;
- private VolumeControlService mService;
- private VolumeControlNativeInterface mNativeInterface;
-
- private final BluetoothDevice mDevice;
-
VolumeControlStateMachine(
- BluetoothDevice device,
VolumeControlService svc,
+ BluetoothDevice device,
VolumeControlNativeInterface nativeInterface,
Looper looper) {
-
super(TAG, looper);
mDevice = device;
mService = svc;
@@ -84,27 +86,11 @@ public class VolumeControlStateMachine extends StateMachine {
setInitialState(mDisconnected);
}
- static VolumeControlStateMachine make(
- BluetoothDevice device,
- VolumeControlService svc,
- VolumeControlNativeInterface nativeInterface,
- Looper looper) {
- Log.i(TAG, "make for device " + device);
- VolumeControlStateMachine VolumeControlSm =
- new VolumeControlStateMachine(device, svc, nativeInterface, looper);
- VolumeControlSm.start();
- return VolumeControlSm;
- }
-
public void doQuit() {
log("doQuit for device " + mDevice);
quitNow();
}
- public void cleanup() {
- log("cleanup for device " + mDevice);
- }
-
@VisibleForTesting
class Disconnected extends State {
@Override
@@ -116,11 +102,11 @@ public class VolumeControlStateMachine extends StateMachine {
+ "): "
+ messageWhatToString(getCurrentMessage().what));
- removeDeferredMessages(DISCONNECT);
+ removeDeferredMessages(MESSAGE_DISCONNECT);
if (mLastConnectionState != -1) {
// Don't broadcast during startup
- broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTED, mLastConnectionState);
+ broadcastConnectionState(STATE_DISCONNECTED, mLastConnectionState);
}
}
@@ -131,7 +117,7 @@ public class VolumeControlStateMachine extends StateMachine {
+ mDevice
+ "): "
+ messageWhatToString(getCurrentMessage().what));
- mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED;
+ mLastConnectionState = STATE_DISCONNECTED;
}
@Override
@@ -143,7 +129,7 @@ public class VolumeControlStateMachine extends StateMachine {
+ messageWhatToString(message.what));
switch (message.what) {
- case CONNECT:
+ case MESSAGE_CONNECT -> {
log("Connecting to " + mDevice);
if (!mNativeInterface.connectVolumeControl(mDevice)) {
Log.e(TAG, "Disconnected: error connecting to " + mDevice);
@@ -157,27 +143,26 @@ public class VolumeControlStateMachine extends StateMachine {
TAG,
"Outgoing VolumeControl Connecting request rejected: " + mDevice);
}
- break;
- case DISCONNECT:
+ }
+ case MESSAGE_DISCONNECT -> {
Log.w(TAG, "Disconnected: DISCONNECT ignored: " + mDevice);
- break;
- case STACK_EVENT:
+ }
+ case MESSAGE_STACK_EVENT -> {
VolumeControlStackEvent event = (VolumeControlStackEvent) message.obj;
Log.d(TAG, "Disconnected: stack event: " + event);
if (!mDevice.equals(event.device)) {
Log.wtf(TAG, "Device(" + mDevice + "): event mismatch: " + event);
}
switch (event.type) {
- case VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED:
+ case VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED -> {
processConnectionEvent(event.valueInt1);
- break;
- default:
- Log.e(TAG, "Disconnected: ignoring stack event: " + event);
- break;
+ }
+ default -> Log.e(TAG, "Disconnected: ignoring stack event: " + event);
}
- break;
- default:
+ }
+ default -> {
return NOT_HANDLED;
+ }
}
return HANDLED;
}
@@ -185,10 +170,7 @@ public class VolumeControlStateMachine extends StateMachine {
// in Disconnected state
private void processConnectionEvent(int state) {
switch (state) {
- case VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTED:
- Log.w(TAG, "Ignore VolumeControl DISCONNECTED event: " + mDevice);
- break;
- case VolumeControlStackEvent.CONNECTION_STATE_CONNECTING:
+ case STATE_CONNECTING -> {
if (mService.okToConnect(mDevice)) {
Log.i(
TAG,
@@ -201,8 +183,8 @@ public class VolumeControlStateMachine extends StateMachine {
"Incoming Volume Control Connecting request rejected: " + mDevice);
mNativeInterface.disconnectVolumeControl(mDevice);
}
- break;
- case VolumeControlStackEvent.CONNECTION_STATE_CONNECTED:
+ }
+ case STATE_CONNECTED -> {
Log.w(TAG, "VolumeControl Connected from Disconnected state: " + mDevice);
if (mService.okToConnect(mDevice)) {
Log.i(
@@ -214,13 +196,8 @@ public class VolumeControlStateMachine extends StateMachine {
Log.w(TAG, "Incoming VolumeControl Connected request rejected: " + mDevice);
mNativeInterface.disconnectVolumeControl(mDevice);
}
- break;
- case VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTING:
- Log.w(TAG, "Ignore VolumeControl DISCONNECTING event: " + mDevice);
- break;
- default:
- Log.e(TAG, "Incorrect state: " + state + " device: " + mDevice);
- break;
+ }
+ default -> Log.e(TAG, "Incorrect state: " + state + " device: " + mDevice);
}
}
}
@@ -235,8 +212,8 @@ public class VolumeControlStateMachine extends StateMachine {
+ mDevice
+ "): "
+ messageWhatToString(getCurrentMessage().what));
- sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs);
- broadcastConnectionState(BluetoothProfile.STATE_CONNECTING, mLastConnectionState);
+ sendMessageDelayed(MESSAGE_CONNECT_TIMEOUT, CONNECT_TIMEOUT.toMillis());
+ broadcastConnectionState(STATE_CONNECTING, mLastConnectionState);
}
@Override
@@ -246,8 +223,8 @@ public class VolumeControlStateMachine extends StateMachine {
+ mDevice
+ "): "
+ messageWhatToString(getCurrentMessage().what));
- mLastConnectionState = BluetoothProfile.STATE_CONNECTING;
- removeMessages(CONNECT_TIMEOUT);
+ mLastConnectionState = STATE_CONNECTING;
+ removeMessages(MESSAGE_CONNECT_TIMEOUT);
}
@Override
@@ -259,42 +236,38 @@ public class VolumeControlStateMachine extends StateMachine {
+ messageWhatToString(message.what));
switch (message.what) {
- case CONNECT:
- deferMessage(message);
- break;
- case CONNECT_TIMEOUT:
+ case MESSAGE_CONNECT -> deferMessage(message);
+ case MESSAGE_CONNECT_TIMEOUT -> {
Log.w(TAG, "Connecting connection timeout: " + mDevice);
mNativeInterface.disconnectVolumeControl(mDevice);
VolumeControlStackEvent disconnectEvent =
new VolumeControlStackEvent(
VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
disconnectEvent.device = mDevice;
- disconnectEvent.valueInt1 =
- VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTED;
- sendMessage(STACK_EVENT, disconnectEvent);
- break;
- case DISCONNECT:
+ disconnectEvent.valueInt1 = STATE_DISCONNECTED;
+ sendMessage(MESSAGE_STACK_EVENT, disconnectEvent);
+ }
+ case MESSAGE_DISCONNECT -> {
log("Connecting: connection canceled to " + mDevice);
mNativeInterface.disconnectVolumeControl(mDevice);
transitionTo(mDisconnected);
- break;
- case STACK_EVENT:
+ }
+ case MESSAGE_STACK_EVENT -> {
VolumeControlStackEvent event = (VolumeControlStackEvent) message.obj;
log("Connecting: stack event: " + event);
if (!mDevice.equals(event.device)) {
Log.wtf(TAG, "Device(" + mDevice + "): event mismatch: " + event);
}
switch (event.type) {
- case VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED:
+ case VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED -> {
processConnectionEvent(event.valueInt1);
- break;
- default:
- Log.e(TAG, "Connecting: ignoring stack event: " + event);
- break;
+ }
+ default -> Log.e(TAG, "Connecting: ignoring stack event: " + event);
}
- break;
- default:
+ }
+ default -> {
return NOT_HANDLED;
+ }
}
return HANDLED;
}
@@ -302,41 +275,29 @@ public class VolumeControlStateMachine extends StateMachine {
// in Connecting state
private void processConnectionEvent(int state) {
switch (state) {
- case VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTED:
+ case STATE_DISCONNECTED -> {
Log.w(TAG, "Connecting device disconnected: " + mDevice);
transitionTo(mDisconnected);
- break;
- case VolumeControlStackEvent.CONNECTION_STATE_CONNECTED:
- transitionTo(mConnected);
- break;
- case VolumeControlStackEvent.CONNECTION_STATE_CONNECTING:
- break;
- case VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTING:
+ }
+ case STATE_CONNECTED -> transitionTo(mConnected);
+ case STATE_DISCONNECTING -> {
Log.w(TAG, "Connecting interrupted: device is disconnecting: " + mDevice);
transitionTo(mDisconnecting);
- break;
- default:
- Log.e(TAG, "Incorrect state: " + state);
- break;
+ }
+ default -> Log.e(TAG, "Incorrect state: " + state);
}
}
}
int getConnectionState() {
String currentState = getCurrentState().getName();
- switch (currentState) {
- case "Disconnected":
- return BluetoothProfile.STATE_DISCONNECTED;
- case "Connecting":
- return BluetoothProfile.STATE_CONNECTING;
- case "Connected":
- return BluetoothProfile.STATE_CONNECTED;
- case "Disconnecting":
- return BluetoothProfile.STATE_DISCONNECTING;
- default:
- Log.e(TAG, "Bad currentState: " + currentState);
- return BluetoothProfile.STATE_DISCONNECTED;
- }
+ return switch (currentState) {
+ case "Disconnected" -> STATE_DISCONNECTED;
+ case "Connecting" -> STATE_CONNECTING;
+ case "Connected" -> STATE_CONNECTED;
+ case "Disconnecting" -> STATE_DISCONNECTING;
+ default -> STATE_DISCONNECTED;
+ };
}
@VisibleForTesting
@@ -349,8 +310,8 @@ public class VolumeControlStateMachine extends StateMachine {
+ mDevice
+ "): "
+ messageWhatToString(getCurrentMessage().what));
- sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs);
- broadcastConnectionState(BluetoothProfile.STATE_DISCONNECTING, mLastConnectionState);
+ sendMessageDelayed(MESSAGE_CONNECT_TIMEOUT, CONNECT_TIMEOUT.toMillis());
+ broadcastConnectionState(STATE_DISCONNECTING, mLastConnectionState);
}
@Override
@@ -360,8 +321,8 @@ public class VolumeControlStateMachine extends StateMachine {
+ mDevice
+ "): "
+ messageWhatToString(getCurrentMessage().what));
- mLastConnectionState = BluetoothProfile.STATE_DISCONNECTING;
- removeMessages(CONNECT_TIMEOUT);
+ mLastConnectionState = STATE_DISCONNECTING;
+ removeMessages(MESSAGE_CONNECT_TIMEOUT);
}
@Override
@@ -373,43 +334,33 @@ public class VolumeControlStateMachine extends StateMachine {
+ messageWhatToString(message.what));
switch (message.what) {
- case CONNECT:
- deferMessage(message);
- break;
- case CONNECT_TIMEOUT:
- {
- Log.w(TAG, "Disconnecting connection timeout: " + mDevice);
- mNativeInterface.disconnectVolumeControl(mDevice);
- VolumeControlStackEvent disconnectEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent
- .EVENT_TYPE_CONNECTION_STATE_CHANGED);
- disconnectEvent.device = mDevice;
- disconnectEvent.valueInt1 =
- VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTED;
- sendMessage(STACK_EVENT, disconnectEvent);
- break;
- }
- case DISCONNECT:
- deferMessage(message);
- break;
- case STACK_EVENT:
+ case MESSAGE_CONNECT, MESSAGE_DISCONNECT -> deferMessage(message);
+ case MESSAGE_CONNECT_TIMEOUT -> {
+ Log.w(TAG, "Disconnecting connection timeout: " + mDevice);
+ mNativeInterface.disconnectVolumeControl(mDevice);
+ VolumeControlStackEvent disconnectEvent =
+ new VolumeControlStackEvent(
+ VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+ disconnectEvent.device = mDevice;
+ disconnectEvent.valueInt1 = STATE_DISCONNECTED;
+ sendMessage(MESSAGE_STACK_EVENT, disconnectEvent);
+ }
+ case MESSAGE_STACK_EVENT -> {
VolumeControlStackEvent event = (VolumeControlStackEvent) message.obj;
log("Disconnecting: stack event: " + event);
if (!mDevice.equals(event.device)) {
Log.wtf(TAG, "Device(" + mDevice + "): event mismatch: " + event);
}
switch (event.type) {
- case VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED:
+ case VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED -> {
processConnectionEvent(event.valueInt1);
- break;
- default:
- Log.e(TAG, "Disconnecting: ignoring stack event: " + event);
- break;
+ }
+ default -> Log.e(TAG, "Disconnecting: ignoring stack event: " + event);
}
- break;
- default:
+ }
+ default -> {
return NOT_HANDLED;
+ }
}
return HANDLED;
}
@@ -417,11 +368,11 @@ public class VolumeControlStateMachine extends StateMachine {
// in Disconnecting state
private void processConnectionEvent(int state) {
switch (state) {
- case VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTED:
+ case STATE_DISCONNECTED -> {
Log.i(TAG, "Disconnected: " + mDevice);
transitionTo(mDisconnected);
- break;
- case VolumeControlStackEvent.CONNECTION_STATE_CONNECTED:
+ }
+ case STATE_CONNECTED -> {
if (mService.okToConnect(mDevice)) {
Log.w(TAG, "Disconnecting interrupted: device is connected: " + mDevice);
transitionTo(mConnected);
@@ -430,8 +381,8 @@ public class VolumeControlStateMachine extends StateMachine {
Log.w(TAG, "Incoming VolumeControl Connected request rejected: " + mDevice);
mNativeInterface.disconnectVolumeControl(mDevice);
}
- break;
- case VolumeControlStackEvent.CONNECTION_STATE_CONNECTING:
+ }
+ case STATE_CONNECTING -> {
if (mService.okToConnect(mDevice)) {
Log.i(TAG, "Disconnecting interrupted: try to reconnect: " + mDevice);
transitionTo(mConnecting);
@@ -442,12 +393,8 @@ public class VolumeControlStateMachine extends StateMachine {
"Incoming VolumeControl Connecting request rejected: " + mDevice);
mNativeInterface.disconnectVolumeControl(mDevice);
}
- break;
- case VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTING:
- break;
- default:
- Log.e(TAG, "Incorrect state: " + state);
- break;
+ }
+ default -> Log.e(TAG, "Incorrect state: " + state);
}
}
}
@@ -462,8 +409,8 @@ public class VolumeControlStateMachine extends StateMachine {
+ mDevice
+ "): "
+ messageWhatToString(getCurrentMessage().what));
- removeDeferredMessages(CONNECT);
- broadcastConnectionState(BluetoothProfile.STATE_CONNECTED, mLastConnectionState);
+ removeDeferredMessages(MESSAGE_CONNECT);
+ broadcastConnectionState(STATE_CONNECTED, mLastConnectionState);
}
@Override
@@ -473,7 +420,7 @@ public class VolumeControlStateMachine extends StateMachine {
+ mDevice
+ "): "
+ messageWhatToString(getCurrentMessage().what));
- mLastConnectionState = BluetoothProfile.STATE_CONNECTED;
+ mLastConnectionState = STATE_CONNECTED;
}
@Override
@@ -481,10 +428,10 @@ public class VolumeControlStateMachine extends StateMachine {
log("Connected process message(" + mDevice + "): " + messageWhatToString(message.what));
switch (message.what) {
- case CONNECT:
+ case MESSAGE_CONNECT -> {
Log.w(TAG, "Connected: CONNECT ignored: " + mDevice);
- break;
- case DISCONNECT:
+ }
+ case MESSAGE_DISCONNECT -> {
log("Disconnecting from " + mDevice);
if (!mNativeInterface.disconnectVolumeControl(mDevice)) {
// If error in the native stack, transition directly to Disconnected state.
@@ -493,24 +440,25 @@ public class VolumeControlStateMachine extends StateMachine {
break;
}
transitionTo(mDisconnecting);
- break;
- case STACK_EVENT:
+ }
+ case MESSAGE_STACK_EVENT -> {
VolumeControlStackEvent event = (VolumeControlStackEvent) message.obj;
log("Connected: stack event: " + event);
if (!mDevice.equals(event.device)) {
Log.wtf(TAG, "Device(" + mDevice + "): event mismatch: " + event);
}
switch (event.type) {
- case VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED:
+ case VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED -> {
processConnectionEvent(event.valueInt1);
- break;
- default:
+ }
+ default -> {
Log.e(TAG, "Connected: ignoring stack event: " + event);
- break;
+ }
}
- break;
- default:
+ }
+ default -> {
return NOT_HANDLED;
+ }
}
return HANDLED;
}
@@ -518,17 +466,16 @@ public class VolumeControlStateMachine extends StateMachine {
// in Connected state
private void processConnectionEvent(int state) {
switch (state) {
- case VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTED:
+ case STATE_DISCONNECTED -> {
Log.i(TAG, "Disconnected from " + mDevice);
transitionTo(mDisconnected);
- break;
- case VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTING:
+ }
+ case STATE_DISCONNECTING -> {
Log.i(TAG, "Disconnecting from " + mDevice);
transitionTo(mDisconnecting);
- break;
- default:
- Log.e(TAG, "Connection State Device: " + mDevice + " bad state: " + state);
- break;
+ }
+ default ->
+ Log.e(TAG, "Connection State Device: " + mDevice + " bad state: " + state);
}
}
}
@@ -547,9 +494,9 @@ public class VolumeControlStateMachine extends StateMachine {
"Connection state "
+ mDevice
+ ": "
- + profileStateToString(prevState)
+ + getConnectionStateName(prevState)
+ "->"
- + profileStateToString(newState));
+ + getConnectionStateName(newState));
mService.handleConnectionStateChanged(mDevice, prevState, newState);
Intent intent = new Intent(BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED);
@@ -563,35 +510,13 @@ public class VolumeControlStateMachine extends StateMachine {
}
private static String messageWhatToString(int what) {
- switch (what) {
- case CONNECT:
- return "CONNECT";
- case DISCONNECT:
- return "DISCONNECT";
- case STACK_EVENT:
- return "STACK_EVENT";
- case CONNECT_TIMEOUT:
- return "CONNECT_TIMEOUT";
- default:
- break;
- }
- return Integer.toString(what);
- }
-
- private static String profileStateToString(int state) {
- switch (state) {
- case BluetoothProfile.STATE_DISCONNECTED:
- return "DISCONNECTED";
- case BluetoothProfile.STATE_CONNECTING:
- return "CONNECTING";
- case BluetoothProfile.STATE_CONNECTED:
- return "CONNECTED";
- case BluetoothProfile.STATE_DISCONNECTING:
- return "DISCONNECTING";
- default:
- break;
- }
- return Integer.toString(state);
+ return switch (what) {
+ case MESSAGE_CONNECT -> "CONNECT";
+ case MESSAGE_DISCONNECT -> "DISCONNECT";
+ case MESSAGE_STACK_EVENT -> "STACK_EVENT";
+ case MESSAGE_CONNECT_TIMEOUT -> "CONNECT_TIMEOUT";
+ default -> Integer.toString(what);
+ };
}
public void dump(StringBuilder sb) {
@@ -611,9 +536,4 @@ public class VolumeControlStateMachine extends StateMachine {
}
scanner.close();
}
-
- @Override
- protected void log(String msg) {
- super.log(msg);
- }
}
diff --git a/android/app/tests/unit/Android.bp b/android/app/tests/unit/Android.bp
index e65bf03f65..979650019d 100644
--- a/android/app/tests/unit/Android.bp
+++ b/android/app/tests/unit/Android.bp
@@ -41,6 +41,7 @@ java_defaults {
"truth",
],
+ jarjar_rules: ":bluetooth-jarjar-rules",
asset_dirs: ["src/com/android/bluetooth/btservice/storage/schemas"],
// Include all test java files.
diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java
index ac848668af..12a0f7d9ef 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientServiceTest.java
@@ -62,6 +62,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder;
+import android.os.Handler;
import android.os.Message;
import android.os.ParcelUuid;
import android.os.RemoteException;
@@ -784,7 +785,8 @@ public class BassClientServiceTest {
@Test
@EnableFlags(Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE)
- public void testNotRemovingCachedBroadcastOnLostWithoutScanning() {
+ @DisableFlags(Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER)
+ public void testNotRemovingCachedBroadcastOnLostWithoutScanning_noResyncFlag() {
prepareConnectedDeviceGroup();
startSearchingForSources();
@@ -814,7 +816,47 @@ public class BassClientServiceTest {
throw e.rethrowFromSystemServer();
}
- // Scan and sync again
+ // Add broadcast to cache
+ onScanResult(mSourceDevice, TEST_BROADCAST_ID);
+ mInOrderMethodProxy
+ .verify(mMethodProxy)
+ .periodicAdvertisingManagerRegisterSync(
+ any(), any(), anyInt(), anyInt(), any(), any());
+
+ // Stop searching
+ mBassClientService.stopSearchingForSources();
+
+ // Add sync handle by add source
+ mBassClientService.addSource(mCurrentDevice, meta, true);
+ handleHandoverSupport();
+ mInOrderMethodProxy
+ .verify(mMethodProxy)
+ .periodicAdvertisingManagerRegisterSync(
+ any(), any(), anyInt(), anyInt(), any(), any());
+ onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE);
+
+ // Sync lost without active scanning should not remove broadcast cache
+ onSyncLost();
+
+ // Add source to unsynced broadcast, causes synchronization first
+ mBassClientService.addSource(mCurrentDevice, meta, true);
+ handleHandoverSupport();
+ mInOrderMethodProxy
+ .verify(mMethodProxy)
+ .periodicAdvertisingManagerRegisterSync(
+ any(), any(), anyInt(), anyInt(), any(), any());
+ }
+
+ @Test
+ @EnableFlags({
+ Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE,
+ Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER
+ })
+ public void testNotRemovingCachedBroadcastOnLostWithoutScanning() {
+ prepareConnectedDeviceGroup();
+ startSearchingForSources();
+
+ // Scan and sync 1
onScanResult(mSourceDevice, TEST_BROADCAST_ID);
mInOrderMethodProxy
.verify(mMethodProxy)
@@ -822,11 +864,47 @@ public class BassClientServiceTest {
any(), any(), anyInt(), anyInt(), any(), any());
onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE);
+ // Sync lost during scanning removes cached broadcast
+ onSyncLost();
+ checkAndDispatchTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_SYNC_LOST_TIMEOUT);
+
+ // Add source to not cached broadcast cause addFailed notification
+ BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID);
+ mBassClientService.addSource(mCurrentDevice, meta, true);
+ handleHandoverSupport();
+ TestUtils.waitForLooperToFinishScheduledTask(mBassClientService.getCallbacks().getLooper());
+ try {
+ verify(mCallback)
+ .onSourceAddFailed(
+ eq(mCurrentDevice),
+ eq(meta),
+ eq(BluetoothStatusCodes.ERROR_BAD_PARAMETERS));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ // Add broadcast to cache
+ onScanResult(mSourceDevice, TEST_BROADCAST_ID);
+ mInOrderMethodProxy
+ .verify(mMethodProxy)
+ .periodicAdvertisingManagerRegisterSync(
+ any(), any(), anyInt(), anyInt(), any(), any());
+
// Stop searching
mBassClientService.stopSearchingForSources();
+ // Add sync handle by add source
+ mBassClientService.addSource(mCurrentDevice, meta, true);
+ handleHandoverSupport();
+ mInOrderMethodProxy
+ .verify(mMethodProxy)
+ .periodicAdvertisingManagerRegisterSync(
+ any(), any(), anyInt(), anyInt(), any(), any());
+ onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE);
+
// Sync lost without active scanning should not remove broadcast cache
onSyncLost();
+ checkAndDispatchTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_SYNC_LOST_TIMEOUT);
// Add source to unsynced broadcast, causes synchronization first
mBassClientService.addSource(mCurrentDevice, meta, true);
@@ -1115,20 +1193,20 @@ public class BassClientServiceTest {
any(), any(), anyInt(), anyInt(), any(), any());
}
- private void checkNoMessage(int message) {
- assertThat(mBassClientService.mHandler.hasMessages(message)).isFalse();
+ private void checkNoTimeout(int broadcastId, int message) {
+ assertThat(mBassClientService.mTimeoutHandler.isStarted(broadcastId, message)).isFalse();
}
- private void checkMessage(int message) {
- assertThat(mBassClientService.mHandler.hasMessages(message)).isTrue();
+ private void checkTimeout(int broadcastId, int message) {
+ assertThat(mBassClientService.mTimeoutHandler.isStarted(broadcastId, message)).isTrue();
}
- private void checkAndDispatchMessage(int message, int broadcastId) {
- checkMessage(message);
- mBassClientService.mHandler.removeMessages(message);
- Message newMsg = mBassClientService.mHandler.obtainMessage(message);
- newMsg.arg1 = broadcastId;
- mBassClientService.mHandler.dispatchMessage(newMsg);
+ private void checkAndDispatchTimeout(int broadcastId, int message) {
+ checkTimeout(broadcastId, message);
+ mBassClientService.mTimeoutHandler.stop(broadcastId, message);
+ Handler handler = mBassClientService.mTimeoutHandler.getOrCreateHandler(broadcastId);
+ Message newMsg = handler.obtainMessage(message);
+ handler.dispatchMessage(newMsg);
}
@Test
@@ -1154,7 +1232,8 @@ public class BassClientServiceTest {
handleHandoverSupport();
// Source synced which cause start timeout event
- checkNoMessage(BassClientService.MESSAGE_SYNC_TIMEOUT);
+ assertThat(mBassClientService.mHandler.hasMessages(BassClientService.MESSAGE_SYNC_TIMEOUT))
+ .isFalse();
onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE);
assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(1);
@@ -1163,7 +1242,13 @@ public class BassClientServiceTest {
assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE))
.isEqualTo(TEST_BROADCAST_ID);
- checkAndDispatchMessage(BassClientService.MESSAGE_SYNC_TIMEOUT, TEST_BROADCAST_ID);
+ assertThat(mBassClientService.mHandler.hasMessages(BassClientService.MESSAGE_SYNC_TIMEOUT))
+ .isTrue();
+ mBassClientService.mHandler.removeMessages(BassClientService.MESSAGE_SYNC_TIMEOUT);
+ Message newMsg =
+ mBassClientService.mHandler.obtainMessage(BassClientService.MESSAGE_SYNC_TIMEOUT);
+ newMsg.arg1 = TEST_BROADCAST_ID;
+ mBassClientService.mHandler.dispatchMessage(newMsg);
// Check if unsyced
mInOrderMethodProxy
@@ -1194,9 +1279,11 @@ public class BassClientServiceTest {
handleHandoverSupport();
// Source synced which cause start timeout event
- checkNoMessage(BassClientService.MESSAGE_SYNC_TIMEOUT);
+ assertThat(mBassClientService.mHandler.hasMessages(BassClientService.MESSAGE_SYNC_TIMEOUT))
+ .isFalse();
onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE);
- checkMessage(BassClientService.MESSAGE_SYNC_TIMEOUT);
+ assertThat(mBassClientService.mHandler.hasMessages(BassClientService.MESSAGE_SYNC_TIMEOUT))
+ .isTrue();
assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(1);
assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE))
@@ -1206,7 +1293,8 @@ public class BassClientServiceTest {
// Start searching again should clear timeout
startSearchingForSources();
- checkNoMessage(BassClientService.MESSAGE_SYNC_TIMEOUT);
+ assertThat(mBassClientService.mHandler.hasMessages(BassClientService.MESSAGE_SYNC_TIMEOUT))
+ .isFalse();
mInOrderMethodProxy
.verify(mMethodProxy, never())
@@ -1549,6 +1637,38 @@ public class BassClientServiceTest {
}
}
+ private void injectRemoteSourceStateChanged(
+ BluetoothLeBroadcastMetadata meta, int paSynState, boolean isBisSynced) {
+ for (BassClientStateMachine sm : mStateMachines.values()) {
+ // Update receiver state
+ if (sm.getDevice().equals(mCurrentDevice)) {
+ injectRemoteSourceStateChanged(
+ sm,
+ meta,
+ TEST_SOURCE_ID,
+ paSynState,
+ meta.isEncrypted()
+ ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING
+ : BluetoothLeBroadcastReceiveState
+ .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
+ null,
+ isBisSynced ? (long) 0x00000001 : (long) 0x00000000);
+ } else if (sm.getDevice().equals(mCurrentDevice1)) {
+ injectRemoteSourceStateChanged(
+ sm,
+ meta,
+ TEST_SOURCE_ID + 1,
+ paSynState,
+ meta.isEncrypted()
+ ? BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_DECRYPTING
+ : BluetoothLeBroadcastReceiveState
+ .BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
+ null,
+ isBisSynced ? (long) 0x00000002 : (long) 0x00000000);
+ }
+ }
+ }
+
private void injectRemoteSourceStateRemoval(BassClientStateMachine sm, int sourceId) {
List<BluetoothLeBroadcastReceiveState> stateList = sm.getAllSources();
if (stateList == null) {
@@ -3155,11 +3275,11 @@ public class BassClientServiceTest {
mInOrderMethodProxy
.verify(mMethodProxy)
.periodicAdvertisingManagerUnregisterSync(any(), any());
- onSyncEstablished(device5, handle5);
mInOrderMethodProxy
.verify(mMethodProxy)
.periodicAdvertisingManagerRegisterSync(
any(), any(), anyInt(), anyInt(), any(), any());
+ onSyncEstablished(device5, handle5);
assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(4);
assertThat(mBassClientService.getActiveSyncedSources())
.containsExactly(handle2, handle3, handle4, handle5)
@@ -4127,8 +4247,8 @@ public class BassClientServiceTest {
verify(mLeAudioService).activeBroadcastAssistantNotification(eq(true));
Mockito.clearInvocations(mLeAudioService);
- /* Imitate broadcast source stop, sink notify about loosing BIS sync */
- injectRemoteSourceStateChanged(meta, true, false);
+ /* Imitate broadcast source stop, sink notify about loosing PA and BIS sync */
+ injectRemoteSourceStateChanged(meta, false, false);
/* Unicast would like to stream */
mBassClientService.cacheSuspendingSources(TEST_BROADCAST_ID);
@@ -4165,8 +4285,8 @@ public class BassClientServiceTest {
0 /* STATUS_LOCAL_STREAM_REQUESTED */);
if (Flags.leaudioBroadcastAssistantPeripheralEntrustment()) {
- /* Imitate broadcast source stop, sink notify about loosing BIS sync */
- injectRemoteSourceStateChanged(meta, true, false);
+ /* Imitate broadcast source stop, sink notify about loosing PA and BIS sync */
+ injectRemoteSourceStateChanged(meta, false, false);
} else {
verifyRemoveMessageAndInjectSourceRemoval();
}
@@ -5351,6 +5471,51 @@ public class BassClientServiceTest {
@Test
@EnableFlags(Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE)
+ @DisableFlags(Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER)
+ public void onSyncLost_notifySourceLostAndCancelSync_noResyncFlag() {
+ prepareConnectedDeviceGroup();
+ startSearchingForSources();
+ onScanResult(mSourceDevice, TEST_BROADCAST_ID);
+ mInOrderMethodProxy
+ .verify(mMethodProxy)
+ .periodicAdvertisingManagerRegisterSync(
+ any(), any(), anyInt(), anyInt(), any(), any());
+ onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE);
+ assertThat(mBassClientService.getActiveSyncedSources().size()).isEqualTo(1);
+ assertThat(mBassClientService.getActiveSyncedSources()).containsExactly(TEST_SYNC_HANDLE);
+ assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE))
+ .isEqualTo(mSourceDevice);
+ assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE))
+ .isEqualTo(TEST_BROADCAST_ID);
+
+ onSyncLost();
+
+ TestUtils.waitForLooperToFinishScheduledTask(mBassClientService.getCallbacks().getLooper());
+ try {
+ verify(mCallback).onSourceLost(eq(TEST_BROADCAST_ID));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ // Cleaned all
+ assertThat(mBassClientService.getActiveSyncedSources()).isEmpty();
+ assertThat(mBassClientService.getDeviceForSyncHandle(TEST_SYNC_HANDLE)).isEqualTo(null);
+ assertThat(mBassClientService.getBroadcastIdForSyncHandle(TEST_SYNC_HANDLE))
+ .isEqualTo(BassConstants.INVALID_BROADCAST_ID);
+
+ // Could try to sync again
+ onScanResult(mSourceDevice, TEST_BROADCAST_ID);
+ mInOrderMethodProxy
+ .verify(mMethodProxy)
+ .periodicAdvertisingManagerRegisterSync(
+ any(), any(), anyInt(), anyInt(), any(), any());
+ }
+
+ @Test
+ @EnableFlags({
+ Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE,
+ Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER
+ })
public void onSyncLost_notifySourceLostAndCancelSync() {
prepareConnectedDeviceGroup();
startSearchingForSources();
@@ -5368,6 +5533,7 @@ public class BassClientServiceTest {
.isEqualTo(TEST_BROADCAST_ID);
onSyncLost();
+ checkAndDispatchTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_SYNC_LOST_TIMEOUT);
TestUtils.waitForLooperToFinishScheduledTask(mBassClientService.getCallbacks().getLooper());
try {
@@ -5390,6 +5556,92 @@ public class BassClientServiceTest {
any(), any(), anyInt(), anyInt(), any(), any());
}
+ @Test
+ @EnableFlags({
+ Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE,
+ Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER
+ })
+ public void monitorBroadcastAfterSyncMaxLimit() {
+ final BluetoothDevice device1 =
+ mBluetoothAdapter.getRemoteLeDevice(
+ "00:11:22:33:44:11", BluetoothDevice.ADDRESS_TYPE_RANDOM);
+ final BluetoothDevice device2 =
+ mBluetoothAdapter.getRemoteLeDevice(
+ "00:11:22:33:44:22", BluetoothDevice.ADDRESS_TYPE_RANDOM);
+ final BluetoothDevice device3 =
+ mBluetoothAdapter.getRemoteLeDevice(
+ "00:11:22:33:44:33", BluetoothDevice.ADDRESS_TYPE_RANDOM);
+ final BluetoothDevice device4 =
+ mBluetoothAdapter.getRemoteLeDevice(
+ "00:11:22:33:44:44", BluetoothDevice.ADDRESS_TYPE_RANDOM);
+ final BluetoothDevice device5 =
+ mBluetoothAdapter.getRemoteLeDevice(
+ "00:11:22:33:44:55", BluetoothDevice.ADDRESS_TYPE_RANDOM);
+ final int handle1 = 0;
+ final int handle2 = 1;
+ final int handle3 = 2;
+ final int handle4 = 3;
+ final int handle5 = 4;
+ final int broadcastId1 = 1111;
+ final int broadcastId2 = 2222;
+ final int broadcastId3 = 3333;
+ final int broadcastId4 = 4444;
+ final int broadcastId5 = 5555;
+
+ prepareConnectedDeviceGroup();
+ startSearchingForSources();
+
+ // Scan and sync 5 sources cause removing 1 synced element
+ onScanResult(device1, broadcastId1);
+ onSyncEstablished(device1, handle1);
+ onScanResult(device2, broadcastId2);
+ onSyncEstablished(device2, handle2);
+ onScanResult(device3, broadcastId3);
+ onSyncEstablished(device3, handle3);
+ onScanResult(device4, broadcastId4);
+ onSyncEstablished(device4, handle4);
+ onScanResult(device5, broadcastId5);
+ mInOrderMethodProxy
+ .verify(mMethodProxy, times(4))
+ .periodicAdvertisingManagerRegisterSync(
+ any(), any(), anyInt(), anyInt(), any(), any());
+ mInOrderMethodProxy
+ .verify(mMethodProxy)
+ .periodicAdvertisingManagerUnregisterSync(any(), any());
+
+ checkTimeout(broadcastId1, BassClientService.MESSAGE_SYNC_LOST_TIMEOUT);
+
+ mInOrderMethodProxy
+ .verify(mMethodProxy)
+ .periodicAdvertisingManagerRegisterSync(
+ any(), any(), anyInt(), anyInt(), any(), any());
+ onSyncEstablished(device5, handle5);
+
+ // Couldn't sync again as broadcast is in the cache
+ onScanResult(device1, broadcastId1);
+ mInOrderMethodProxy
+ .verify(mMethodProxy, never())
+ .periodicAdvertisingManagerRegisterSync(
+ any(), any(), anyInt(), anyInt(), any(), any());
+
+ // Lost should notify about lost and clear cache
+ checkAndDispatchTimeout(broadcastId1, BassClientService.MESSAGE_SYNC_LOST_TIMEOUT);
+
+ TestUtils.waitForLooperToFinishScheduledTask(mBassClientService.getCallbacks().getLooper());
+ try {
+ verify(mCallback).onSourceLost(eq(broadcastId1));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ // Could try to sync again
+ onScanResult(device1, broadcastId1);
+ mInOrderMethodProxy
+ .verify(mMethodProxy)
+ .periodicAdvertisingManagerRegisterSync(
+ any(), any(), anyInt(), anyInt(), any(), any());
+ }
+
private void prepareSynchronizedPair() {
prepareConnectedDeviceGroup();
startSearchingForSources();
@@ -5432,7 +5684,7 @@ public class BassClientServiceTest {
.periodicAdvertisingManagerRegisterSync(
any(), any(), anyInt(), anyInt(), any(), any());
onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE);
- checkMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
+ checkTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
}
private void sinkUnintentionalDuringScanning() {
@@ -5441,7 +5693,7 @@ public class BassClientServiceTest {
// Bis and PA unsynced, SINK_UNINTENTIONAL
BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID);
injectRemoteSourceStateChanged(meta, false, false);
- checkMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
+ checkTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
}
private void checkResumeSynchronizationByBig() {
@@ -5491,16 +5743,16 @@ public class BassClientServiceTest {
}
private void verifyStopBigMonitoringWithUnsync() {
- checkNoMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
- checkNoMessage(BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ checkNoTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
+ checkNoTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
mInOrderMethodProxy
.verify(mMethodProxy)
.periodicAdvertisingManagerUnregisterSync(any(), any());
}
private void verifyStopBigMonitoringWithoutUnsync() {
- checkNoMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
- checkNoMessage(BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ checkNoTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
+ checkNoTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
mInOrderMethodProxy
.verify(mMethodProxy, never())
.periodicAdvertisingManagerUnregisterSync(any(), any());
@@ -5527,14 +5779,14 @@ public class BassClientServiceTest {
.verify(mMethodProxy, never())
.periodicAdvertisingManagerRegisterSync(
any(), any(), anyInt(), anyInt(), any(), any());
- checkNoMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
- checkNoMessage(BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ checkNoTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
+ checkNoTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
}
private void checkSinkPause() {
BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID);
injectRemoteSourceStateChanged(meta, false, false);
- checkMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
+ checkTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
}
@Test
@@ -5807,7 +6059,7 @@ public class BassClientServiceTest {
(long) 0x00000000);
}
}
- checkMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
+ checkTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
// Unsync all sinks cause stop monitoring
for (BassClientStateMachine sm : mStateMachines.values()) {
@@ -5849,7 +6101,7 @@ public class BassClientServiceTest {
(long) 0x00000000);
}
}
- checkMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
+ checkTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
// Unsync all sinks cause stop monitoring
for (BassClientStateMachine sm : mStateMachines.values()) {
@@ -5886,7 +6138,7 @@ public class BassClientServiceTest {
mCurrentDevice,
BluetoothProfile.STATE_CONNECTED,
BluetoothProfile.STATE_DISCONNECTED);
- checkMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
+ checkTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
// Disconnect all sinks cause stop monitoring
doReturn(BluetoothProfile.STATE_DISCONNECTED)
@@ -5918,7 +6170,7 @@ public class BassClientServiceTest {
mCurrentDevice,
BluetoothProfile.STATE_CONNECTED,
BluetoothProfile.STATE_DISCONNECTED);
- checkMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
+ checkTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
// Disconnect all sinks cause stop monitoring
doReturn(BluetoothProfile.STATE_DISCONNECTED)
@@ -5941,10 +6193,10 @@ public class BassClientServiceTest {
public void sinkUnintentional_syncLost_withoutScanning_outOfRange() {
sinkUnintentionalWithoutScanning();
- checkNoMessage(BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ checkNoTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
onSyncLost();
- checkMessage(BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ checkTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
mInOrderMethodProxy
.verify(mMethodProxy)
.periodicAdvertisingManagerRegisterSync(
@@ -5956,8 +6208,8 @@ public class BassClientServiceTest {
.periodicAdvertisingManagerRegisterSync(
any(), any(), anyInt(), anyInt(), any(), any());
- checkAndDispatchMessage(
- BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT, TEST_BROADCAST_ID);
+ checkAndDispatchTimeout(
+ TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
verifyStopBigMonitoringWithUnsync();
verifyRemoveMessageAndInjectSourceRemoval();
checkNoResumeSynchronizationByBig();
@@ -5971,10 +6223,10 @@ public class BassClientServiceTest {
public void sinkUnintentional_syncLost_duringScanning_outOfRange() {
sinkUnintentionalDuringScanning();
- checkNoMessage(BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ checkNoTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
onSyncLost();
- checkMessage(BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ checkTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
mInOrderMethodProxy
.verify(mMethodProxy)
.periodicAdvertisingManagerRegisterSync(
@@ -5986,8 +6238,8 @@ public class BassClientServiceTest {
.periodicAdvertisingManagerRegisterSync(
any(), any(), anyInt(), anyInt(), any(), any());
- checkAndDispatchMessage(
- BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT, TEST_BROADCAST_ID);
+ checkAndDispatchTimeout(
+ TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
verifyStopBigMonitoringWithoutUnsync();
verifyRemoveMessageAndInjectSourceRemoval();
checkNoResumeSynchronizationByBig();
@@ -6001,7 +6253,7 @@ public class BassClientServiceTest {
public void sinkUnintentional_bigMonitorTimeout_withoutScanning() {
sinkUnintentionalWithoutScanning();
- checkAndDispatchMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT, TEST_BROADCAST_ID);
+ checkAndDispatchTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
verifyStopBigMonitoringWithUnsync();
verifyRemoveMessageAndInjectSourceRemoval();
checkNoResumeSynchronizationByBig();
@@ -6015,7 +6267,7 @@ public class BassClientServiceTest {
public void sinkUnintentional_bigMonitorTimeout_duringScanning() {
sinkUnintentionalDuringScanning();
- checkAndDispatchMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT, TEST_BROADCAST_ID);
+ checkAndDispatchTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
verifyStopBigMonitoringWithoutUnsync();
verifyRemoveMessageAndInjectSourceRemoval();
checkNoResumeSynchronizationByBig();
@@ -6371,11 +6623,11 @@ public class BassClientServiceTest {
.verify(mMethodProxy)
.periodicAdvertisingManagerRegisterSync(
any(), any(), anyInt(), anyInt(), any(), any());
- checkMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
- checkNoMessage(BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ checkTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
+ checkNoTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
onSyncEstablishedFailed(mSourceDevice, TEST_SYNC_HANDLE);
- checkMessage(BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ checkTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
mInOrderMethodProxy
.verify(mMethodProxy)
.periodicAdvertisingManagerRegisterSync(
@@ -6387,8 +6639,8 @@ public class BassClientServiceTest {
.periodicAdvertisingManagerRegisterSync(
any(), any(), anyInt(), anyInt(), any(), any());
- checkAndDispatchMessage(
- BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT, TEST_BROADCAST_ID);
+ checkAndDispatchTimeout(
+ TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
verifyStopBigMonitoringWithUnsync();
}
@@ -6407,11 +6659,11 @@ public class BassClientServiceTest {
.verify(mMethodProxy)
.periodicAdvertisingManagerRegisterSync(
any(), any(), anyInt(), anyInt(), any(), any());
- checkMessage(BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
- checkNoMessage(BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ checkTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BIG_MONITOR_TIMEOUT);
+ checkNoTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
onSyncEstablishedFailed(mSourceDevice, TEST_SYNC_HANDLE);
- checkMessage(BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ checkTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
mInOrderMethodProxy
.verify(mMethodProxy)
.periodicAdvertisingManagerRegisterSync(
@@ -6424,7 +6676,7 @@ public class BassClientServiceTest {
any(), any(), anyInt(), anyInt(), any(), any());
onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE);
- checkNoMessage(BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
+ checkNoTimeout(TEST_BROADCAST_ID, BassClientService.MESSAGE_BROADCAST_MONITOR_TIMEOUT);
}
@Test
@@ -6537,4 +6789,145 @@ public class BassClientServiceTest {
assertThat(mBassClientService.isLocalBroadcast(metadata)).isTrue();
assertThat(mBassClientService.isLocalBroadcast(receiveState)).isTrue();
}
+
+ private void verifyInitiatePaSyncTransferAndNoOthers() {
+ expect.that(mStateMachines.size()).isEqualTo(2);
+ for (BassClientStateMachine sm : mStateMachines.values()) {
+ ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ verify(sm, atLeast(1)).sendMessage(messageCaptor.capture());
+ long count;
+ if (sm.getDevice().equals(mCurrentDevice)) {
+ count =
+ messageCaptor.getAllValues().stream()
+ .filter(
+ m ->
+ (m.what
+ == BassClientStateMachine
+ .INITIATE_PA_SYNC_TRANSFER)
+ && (m.arg1 == TEST_SYNC_HANDLE)
+ && (m.arg2 == TEST_SOURCE_ID))
+ .count();
+ assertThat(count).isEqualTo(1);
+ count =
+ messageCaptor.getAllValues().stream()
+ .filter(
+ m ->
+ m.what
+ != BassClientStateMachine
+ .INITIATE_PA_SYNC_TRANSFER)
+ .count();
+ assertThat(count).isEqualTo(0);
+ } else if (sm.getDevice().equals(mCurrentDevice1)) {
+ count =
+ messageCaptor.getAllValues().stream()
+ .filter(
+ m ->
+ (m.what
+ == BassClientStateMachine
+ .INITIATE_PA_SYNC_TRANSFER)
+ && (m.arg1 == TEST_SYNC_HANDLE)
+ && (m.arg2 == TEST_SOURCE_ID + 1))
+ .count();
+ assertThat(count).isEqualTo(1);
+ count =
+ messageCaptor.getAllValues().stream()
+ .filter(
+ m ->
+ m.what
+ != BassClientStateMachine
+ .INITIATE_PA_SYNC_TRANSFER)
+ .count();
+ assertThat(count).isEqualTo(0);
+ } else {
+ throw new AssertionError("Unexpected device");
+ }
+ }
+ }
+
+ @Test
+ @EnableFlags({
+ Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER,
+ Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE
+ })
+ public void initiatePaSyncTransfer() {
+ prepareSynchronizedPairAndStopSearching();
+
+ // Sync info request force syncing to broadcaster and add sinks pending for PAST
+ mBassClientService.syncRequestForPast(mCurrentDevice, TEST_BROADCAST_ID, TEST_SOURCE_ID);
+ mBassClientService.syncRequestForPast(
+ mCurrentDevice1, TEST_BROADCAST_ID, TEST_SOURCE_ID + 1);
+ mInOrderMethodProxy
+ .verify(mMethodProxy)
+ .periodicAdvertisingManagerRegisterSync(
+ any(), any(), anyInt(), anyInt(), any(), any());
+
+ // Sync will INITIATE_PA_SYNC_TRANSFER
+ onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE);
+ verifyInitiatePaSyncTransferAndNoOthers();
+ }
+
+ @Test
+ @EnableFlags({
+ Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER,
+ Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE
+ })
+ public void InitiatePaSyncTransfer_concurrentWithResume() {
+ prepareSynchronizedPairAndStopSearching();
+
+ BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID);
+
+ // Cache sinks for resume and set HOST_INTENTIONAL pause
+ mBassClientService.handleUnicastSourceStreamStatusChange(
+ 0 /* STATUS_LOCAL_STREAM_REQUESTED */);
+ injectRemoteSourceStateChanged(meta, false, false);
+
+ // Resume source will force syncing to broadcaser and put pending source to add
+ mBassClientService.resumeReceiversSourceSynchronization();
+ mInOrderMethodProxy
+ .verify(mMethodProxy)
+ .periodicAdvertisingManagerRegisterSync(
+ any(), any(), anyInt(), anyInt(), any(), any());
+
+ // Sync info request add sinks pending for PAST
+ mBassClientService.syncRequestForPast(mCurrentDevice, TEST_BROADCAST_ID, TEST_SOURCE_ID);
+ mBassClientService.syncRequestForPast(
+ mCurrentDevice1, TEST_BROADCAST_ID, TEST_SOURCE_ID + 1);
+
+ // Sync will send INITIATE_PA_SYNC_TRANSFER and remove pending soure to add
+ onSyncEstablished(mSourceDevice, TEST_SYNC_HANDLE);
+ verifyInitiatePaSyncTransferAndNoOthers();
+ }
+
+ @Test
+ @EnableFlags({
+ Flags.FLAG_LEAUDIO_BROADCAST_RESYNC_HELPER,
+ Flags.FLAG_LEAUDIO_BROADCAST_EXTRACT_PERIODIC_SCANNER_FROM_STATE_MACHINE
+ })
+ public void resumeSourceSynchronization_omitWhenPaSyncedOrRequested() {
+ prepareSynchronizedPair();
+
+ BluetoothLeBroadcastMetadata meta = createBroadcastMetadata(TEST_BROADCAST_ID);
+
+ // Cache sinks for resume and set HOST_INTENTIONAL pause
+ // Try resume while sync info requested
+ mBassClientService.handleUnicastSourceStreamStatusChange(
+ 0 /* STATUS_LOCAL_STREAM_REQUESTED */);
+ injectRemoteSourceStateChanged(
+ meta, BluetoothLeBroadcastReceiveState.PA_SYNC_STATE_SYNCINFO_REQUEST, false);
+ checkNoResumeSynchronizationByHost();
+
+ // Cache sinks for resume and set HOST_INTENTIONAL pause
+ // Try resume while pa synced
+ mBassClientService.handleUnicastSourceStreamStatusChange(
+ 0 /* STATUS_LOCAL_STREAM_REQUESTED */);
+ injectRemoteSourceStateChanged(meta, true, false);
+ checkNoResumeSynchronizationByHost();
+
+ // Cache sinks for resume and set HOST_INTENTIONAL pause
+ // Try resume while pa unsynced
+ mBassClientService.handleUnicastSourceStreamStatusChange(
+ 0 /* STATUS_LOCAL_STREAM_REQUESTED */);
+ injectRemoteSourceStateChanged(meta, false, false);
+ checkResumeSynchronizationByHost();
+ }
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java
index e4ae0e4dd8..696526bb26 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/bass_client/BassClientStateMachineTest.java
@@ -32,6 +32,7 @@ import static com.android.bluetooth.bass_client.BassClientStateMachine.CONNECT_T
import static com.android.bluetooth.bass_client.BassClientStateMachine.DISCONNECT;
import static com.android.bluetooth.bass_client.BassClientStateMachine.GATT_TXN_PROCESSED;
import static com.android.bluetooth.bass_client.BassClientStateMachine.GATT_TXN_TIMEOUT;
+import static com.android.bluetooth.bass_client.BassClientStateMachine.INITIATE_PA_SYNC_TRANSFER;
import static com.android.bluetooth.bass_client.BassClientStateMachine.PSYNC_ACTIVE_TIMEOUT;
import static com.android.bluetooth.bass_client.BassClientStateMachine.REACHED_MAX_SOURCE_LIMIT;
import static com.android.bluetooth.bass_client.BassClientStateMachine.READ_BASS_CHARACTERISTICS;
@@ -894,12 +895,23 @@ public class BassClientStateMachineTest {
when(characteristic.getValue()).thenReturn(value);
when(mBassClientService.getPeriodicAdvertisementResult(any(), anyInt()))
.thenReturn(paResult);
- when(paResult.getSyncHandle()).thenReturn(100);
+ int syncHandle = 100;
+ when(paResult.getSyncHandle()).thenReturn(syncHandle);
Mockito.clearInvocations(callbacks);
cb.onCharacteristicRead(null, characteristic, GATT_SUCCESS);
TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper());
+ int serviceData = 0x000000FF & sourceId;
+ serviceData = serviceData << 8;
+ // advA matches EXT_ADV_ADDRESS
+ // also matches source address (as we would have written)
+ serviceData = serviceData & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_EXT_ADV_ADDRESS);
+ serviceData = serviceData & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS);
+ verify(mMethodProxy)
+ .periodicAdvertisingManagerTransferSync(
+ any(), any(), eq(serviceData), eq(syncHandle));
+
verify(callbacks)
.notifyReceiveStateChanged(any(), eq(sourceId), receiveStateCaptor.capture());
Assert.assertEquals(receiveStateCaptor.getValue().getSourceDevice(), mSourceTestDevice);
@@ -1707,6 +1719,26 @@ public class BassClientStateMachineTest {
}
@Test
+ public void sendInitiatePaSyncTransferMessage_inConnectedState() {
+ initToConnectedState();
+ int syncHandle = 1234;
+ int sourceId = 4321;
+
+ mBassClientStateMachine.sendMessage(INITIATE_PA_SYNC_TRANSFER, syncHandle, sourceId);
+ TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper());
+
+ int serviceData = 0x000000FF & sourceId;
+ serviceData = serviceData << 8;
+ // advA matches EXT_ADV_ADDRESS
+ // also matches source address (as we would have written)
+ serviceData = serviceData & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_EXT_ADV_ADDRESS);
+ serviceData = serviceData & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS);
+ verify(mMethodProxy)
+ .periodicAdvertisingManagerTransferSync(
+ any(), any(), eq(serviceData), eq(syncHandle));
+ }
+
+ @Test
public void sendConnectMessage_inConnectedProcessingState_doesNotChangeState() {
initToConnectedProcessingState();
@@ -1906,6 +1938,11 @@ public class BassClientStateMachineTest {
mBassClientStateMachine.sendMessage(SWITCH_BCAST_SOURCE);
TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper());
assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(SWITCH_BCAST_SOURCE)).isTrue();
+
+ mBassClientStateMachine.sendMessage(INITIATE_PA_SYNC_TRANSFER);
+ TestUtils.waitForLooperToFinishScheduledTask(mHandlerThread.getLooper());
+ assertThat(mBassClientStateMachine.hasDeferredMessagesSuper(INITIATE_PA_SYNC_TRANSFER))
+ .isTrue();
}
@Test
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 b50835e74a..541f965969 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
@@ -24,6 +24,7 @@ import static org.mockito.Mockito.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -67,6 +68,7 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
@@ -87,6 +89,7 @@ public class ActiveDeviceManagerTest {
private BluetoothDevice mHearingAidDevice;
private BluetoothDevice mLeAudioDevice;
private BluetoothDevice mLeAudioDevice2;
+ private BluetoothDevice mLeAudioDevice3;
private BluetoothDevice mLeHearingAidDevice;
private BluetoothDevice mSecondaryAudioDevice;
private BluetoothDevice mDualModeAudioDevice;
@@ -146,6 +149,7 @@ public class ActiveDeviceManagerTest {
mSecondaryAudioDevice = TestUtils.getTestDevice(mAdapter, 6);
mDualModeAudioDevice = TestUtils.getTestDevice(mAdapter, 7);
mLeAudioDevice2 = TestUtils.getTestDevice(mAdapter, 8);
+ mLeAudioDevice3 = TestUtils.getTestDevice(mAdapter, 9);
mDeviceConnectionStack = new ArrayList<>();
mMostRecentDevice = null;
mOriginalDualModeAudioState = Utils.isDualModeAudioEnabled();
@@ -161,6 +165,7 @@ public class ActiveDeviceManagerTest {
when(mLeAudioService.getLeadDevice(mLeAudioDevice)).thenReturn(mLeAudioDevice);
when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice2);
+ when(mLeAudioService.getLeadDevice(mLeAudioDevice3)).thenReturn(mLeAudioDevice3);
when(mLeAudioService.getLeadDevice(mDualModeAudioDevice)).thenReturn(mDualModeAudioDevice);
when(mLeAudioService.getLeadDevice(mLeHearingAidDevice)).thenReturn(mLeHearingAidDevice);
@@ -839,6 +844,161 @@ public class ActiveDeviceManagerTest {
verify(mLeAudioService).setActiveDevice(mLeAudioDevice);
}
+ /**
+ * One LE Audio set, containing two buds, is connected. When one device got disconnected
+ * fallback device should not be set to true active device to fallback device.
+ */
+ @Test
+ @EnableFlags(Flags.FLAG_ADM_FIX_DISCONNECT_OF_SET_MEMBER)
+ public void leAudioSecondDeviceDisconnected_noFallbackDeviceActive_ModeNormal() {
+ when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL);
+
+ InOrder order = inOrder(mLeAudioService);
+
+ int groupId = 1;
+ List<BluetoothDevice> groupDevices = List.of(mLeAudioDevice, mLeAudioDevice2);
+ when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice);
+
+ leAudioConnected(mLeAudioDevice);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService, times(1)).setActiveDevice(mLeAudioDevice);
+
+ leAudioConnected(mLeAudioDevice2);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService, never()).setActiveDevice(any());
+
+ when(mLeAudioService.getGroupId(any())).thenReturn(groupId);
+ when(mLeAudioService.getGroupDevices(groupId)).thenReturn(groupDevices);
+
+ leAudioDisconnected(mLeAudioDevice2);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService, never()).setActiveDevice(any());
+ }
+
+ /**
+ * One LE Audio set, containing two buds, is connected. When one device got disconnected
+ * fallback device should not be set to true active device to fallback device.
+ */
+ @Test
+ @EnableFlags(Flags.FLAG_ADM_FIX_DISCONNECT_OF_SET_MEMBER)
+ public void leAudioSecondDeviceDisconnected_noFallbackDeviceActive_ModeInCall() {
+ when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_IN_CALL);
+
+ InOrder order = inOrder(mLeAudioService);
+
+ int groupId = 1;
+ List<BluetoothDevice> groupDevices = List.of(mLeAudioDevice, mLeAudioDevice2);
+ when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice);
+
+ leAudioConnected(mLeAudioDevice);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService, times(1)).setActiveDevice(mLeAudioDevice);
+
+ leAudioConnected(mLeAudioDevice2);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService, never()).setActiveDevice(any());
+
+ when(mLeAudioService.getGroupId(any())).thenReturn(groupId);
+ when(mLeAudioService.getGroupDevices(groupId)).thenReturn(groupDevices);
+
+ leAudioDisconnected(mLeAudioDevice2);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService, never()).setActiveDevice(any());
+ }
+
+ /**
+ * One LE Audio set, containing two buds, is connected. When one device got disconnected
+ * fallback device should not be set to true active device to fallback device.
+ */
+ @Test
+ @EnableFlags(Flags.FLAG_ADM_FIX_DISCONNECT_OF_SET_MEMBER)
+ public void twoLeAudioSets_OneSetDisconnected_FallbackToAnotherOne_ModeNormal() {
+ when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL);
+
+ InOrder order = inOrder(mLeAudioService);
+
+ int groupId = 1;
+ List<BluetoothDevice> groupDevices = List.of(mLeAudioDevice, mLeAudioDevice2);
+
+ when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice);
+ when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(groupId);
+ when(mLeAudioService.getGroupId(mLeAudioDevice2)).thenReturn(groupId);
+ when(mLeAudioService.getGroupDevices(groupId)).thenReturn(groupDevices);
+
+ int groupId2 = 2;
+ List<BluetoothDevice> groupDevicesId2 = List.of(mLeAudioDevice3);
+
+ when(mLeAudioService.getGroupId(mLeAudioDevice3)).thenReturn(groupId2);
+ when(mLeAudioService.getGroupDevices(groupId2)).thenReturn(groupDevicesId2);
+
+ leAudioConnected(mLeAudioDevice3);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService, times(1)).setActiveDevice(mLeAudioDevice3);
+
+ leAudioConnected(mLeAudioDevice);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService).setActiveDevice(mLeAudioDevice);
+
+ leAudioConnected(mLeAudioDevice2);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService, never()).setActiveDevice(mLeAudioDevice2);
+
+ leAudioDisconnected(mLeAudioDevice2);
+ mTestLooper.dispatchAll();
+ // Should not encrease a number of this call.
+ order.verify(mLeAudioService, never()).setActiveDevice(any());
+
+ leAudioDisconnected(mLeAudioDevice);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService, times(1)).setActiveDevice(mLeAudioDevice3);
+ }
+
+ /**
+ * One LE Audio set, containing two buds, is connected. When one device got disconnected
+ * fallback device should not be set to true active device to fallback device.
+ */
+ @Test
+ @EnableFlags(Flags.FLAG_ADM_FIX_DISCONNECT_OF_SET_MEMBER)
+ public void twoLeAudioSets_OneSetDisconnected_FallbackToAnotherOne_ModeInCall() {
+ when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_IN_CALL);
+
+ InOrder order = inOrder(mLeAudioService);
+
+ int groupId = 1;
+ List<BluetoothDevice> groupDevices = List.of(mLeAudioDevice, mLeAudioDevice2);
+
+ when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice);
+ when(mLeAudioService.getGroupId(mLeAudioDevice)).thenReturn(groupId);
+ when(mLeAudioService.getGroupId(mLeAudioDevice2)).thenReturn(groupId);
+ when(mLeAudioService.getGroupDevices(groupId)).thenReturn(groupDevices);
+
+ int groupId2 = 2;
+ List<BluetoothDevice> groupDevicesId2 = List.of(mLeAudioDevice3);
+
+ when(mLeAudioService.getGroupId(mLeAudioDevice3)).thenReturn(groupId2);
+ when(mLeAudioService.getGroupDevices(groupId2)).thenReturn(groupDevicesId2);
+
+ leAudioConnected(mLeAudioDevice3);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService).setActiveDevice(mLeAudioDevice3);
+
+ leAudioConnected(mLeAudioDevice);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService).setActiveDevice(mLeAudioDevice);
+
+ leAudioConnected(mLeAudioDevice2);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService, never()).setActiveDevice(any());
+
+ leAudioDisconnected(mLeAudioDevice2);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService, never()).setActiveDevice(any());
+
+ leAudioDisconnected(mLeAudioDevice);
+ mTestLooper.dispatchAll();
+ order.verify(mLeAudioService, times(1)).setActiveDevice(mLeAudioDevice3);
+ }
+
/** A combo (A2DP + Headset) device is connected. Then an LE Audio is connected. */
@Test
public void leAudioActive_clearA2dpAndHeadsetActive() {
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 7dadb2cc33..f73e0f064e 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
@@ -346,7 +346,6 @@ public class AdapterServiceTest {
// Restores the foregroundUserId to the ID prior to the test setup
Utils.setForegroundUserId(mForegroundUserId);
- assertThat(mLooper.nextMessage()).isNull();
mAdapterService.cleanup();
mAdapterService.unregisterRemoteCallback(mIBluetoothCallback);
AdapterNativeInterface.setInstance(null);
@@ -567,6 +566,7 @@ public class AdapterServiceTest {
@Test
public void testEnable() {
doEnable(false);
+ assertThat(mLooper.nextMessage()).isNull();
}
@Test
@@ -580,6 +580,7 @@ public class AdapterServiceTest {
verify(mNativeInterface).setScanMode(eq(halExpectedScanMode));
assertThat(mAdapterService.getScanMode()).isEqualTo(expectedScanMode);
+ assertThat(mLooper.nextMessage()).isNull();
}
/** Test: Turn Bluetooth on/off. Check whether the AdapterService gets started and stopped. */
@@ -587,6 +588,7 @@ public class AdapterServiceTest {
public void testEnableDisable() {
doEnable(false);
doDisable(false);
+ assertThat(mLooper.nextMessage()).isNull();
}
/**
@@ -613,6 +615,7 @@ public class AdapterServiceTest {
Config.init(mockContext);
doEnable(true);
doDisable(true);
+ assertThat(mLooper.nextMessage()).isNull();
}
/** Test: Don't start GATT Check whether the AdapterService quits gracefully */
@@ -646,6 +649,7 @@ public class AdapterServiceTest {
verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
+ assertThat(mLooper.nextMessage()).isNull();
}
/** Test: Don't stop GATT Check whether the AdapterService quits gracefully */
@@ -679,6 +683,7 @@ public class AdapterServiceTest {
verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
+ assertThat(mLooper.nextMessage()).isNull();
}
@Test
@@ -691,6 +696,7 @@ public class AdapterServiceTest {
dropNextMessage(MESSAGE_PROFILE_SERVICE_REGISTERED);
dropNextMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
+ assertThat(mLooper.nextMessage()).isNull();
}
@Test
@@ -700,6 +706,7 @@ public class AdapterServiceTest {
assertThat(mAdapterService.getBluetoothGatt()).isNull();
assertThat(mAdapterService.getBluetoothScan()).isNotNull();
+ assertThat(mLooper.nextMessage()).isNull();
}
@Test
@@ -741,6 +748,7 @@ public class AdapterServiceTest {
assertThat(mAdapterService.getBluetoothScan()).isNull();
assertThat(mAdapterService.getBluetoothGatt()).isNull();
+ assertThat(mLooper.nextMessage()).isNull();
}
@Test
@@ -808,6 +816,7 @@ public class AdapterServiceTest {
assertThat(mAdapterService.getState()).isEqualTo(STATE_BLE_ON);
mAdapterService.unregisterRemoteCallback(callback);
+ assertThat(mLooper.nextMessage()).isNull();
}
/** Test: Don't start a classic profile Check whether the AdapterService quits gracefully */
@@ -851,6 +860,7 @@ public class AdapterServiceTest {
// Ensure GATT is still running
assertThat(mAdapterService.getBluetoothGatt()).isNotNull();
+ assertThat(mLooper.nextMessage()).isNull();
}
/** Test: Don't stop a classic profile Check whether the AdapterService quits gracefully */
@@ -885,6 +895,7 @@ public class AdapterServiceTest {
verifyStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
assertThat(mAdapterService.getState()).isEqualTo(STATE_OFF);
+ assertThat(mLooper.nextMessage()).isNull();
}
/** Test: Toggle snoop logging setting Check whether the AdapterService restarts fully */
@@ -933,6 +944,7 @@ public class AdapterServiceTest {
// Restore earlier setting
BluetoothProperties.snoop_log_mode(snoopSetting);
+ assertThat(mLooper.nextMessage()).isNull();
}
/**
@@ -943,6 +955,7 @@ public class AdapterServiceTest {
@Test
public void testObfuscateBluetoothAddress_NullAddress() {
assertThat(mAdapterService.obfuscateAddress(null)).isEmpty();
+ assertThat(mLooper.nextMessage()).isNull();
}
@Test
@@ -963,6 +976,7 @@ public class AdapterServiceTest {
// Verify we can get correct identity address
identityAddress = mAdapterService.getIdentityAddress(TEST_BT_ADDR_1);
assertThat(identityAddress).isEqualTo(TEST_BT_ADDR_2);
+ assertThat(mLooper.nextMessage()).isNull();
}
@Test
@@ -972,6 +986,7 @@ public class AdapterServiceTest {
assertThat(mAdapterService.getByteIdentityAddress(device)).isNull();
assertThat(mAdapterService.getIdentityAddress(device.getAddress())).isNull();
+ assertThat(mLooper.nextMessage()).isNull();
}
public static byte[] getMetricsSalt(Map<String, Map<String, String>> adapterConfig) {
@@ -1021,6 +1036,7 @@ public class AdapterServiceTest {
@Test
public void testGetMetricId_NullAddress() {
assertThat(mAdapterService.getMetricId(null)).isEqualTo(0);
+ assertThat(mLooper.nextMessage()).isNull();
}
@Test
@@ -1033,6 +1049,7 @@ public class AdapterServiceTest {
doReturn(new byte[0]).when(mNativeInterface).dumpMetrics();
mAdapterService.dump(fd, writer, new String[] {"--proto-bin"});
mAdapterService.dump(fd, writer, new String[] {"random", "arguments"});
+ assertThat(mLooper.nextMessage()).isNull();
}
@Test
@@ -1070,5 +1087,6 @@ public class AdapterServiceTest {
Files.deleteIfExists(randomFileUnderBluedroidPath);
Files.deleteIfExists(randomFileUnderBluetoothPath);
}
+ assertThat(mLooper.nextMessage()).isNull();
}
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java
index 6129d25497..845a53b77c 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/RemoteDevicesTest.java
@@ -17,6 +17,8 @@ import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Message;
import android.os.TestLooperManager;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.filters.MediumTest;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -25,6 +27,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.Utils;
import com.android.bluetooth.bas.BatteryService;
import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties;
+import com.android.bluetooth.flags.Flags;
import com.android.bluetooth.hfp.HeadsetHalConstants;
import org.junit.After;
@@ -55,6 +58,7 @@ public class RemoteDevicesTest {
private Context mTargetContext;
private BluetoothManager mBluetoothManager;
+ @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
@@ -761,6 +765,18 @@ public class RemoteDevicesTest {
}
@Test
+ @EnableFlags(Flags.FLAG_FIX_ADD_DEVICE_PROPERTIES)
+ public void testMultipleAddDeviceProperties() {
+ // Verify that device property is null initially
+ Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1));
+ DeviceProperties prop1 =
+ mRemoteDevices.addDeviceProperties(Utils.getBytesFromAddress(TEST_BT_ADDR_1));
+ DeviceProperties prop2 =
+ mRemoteDevices.addDeviceProperties(Utils.getBytesFromAddress(TEST_BT_ADDR_1));
+ Assert.assertEquals(prop2, prop1);
+ }
+
+ @Test
public void testSetgetHfAudioPolicyForRemoteAg() {
// Verify that device property is null initially
Assert.assertNull(mRemoteDevices.getDeviceProperties(mDevice1));
diff --git a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java
index eb0e166a77..4195b96536 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/hfp/HeadsetServiceAndStateMachineTest.java
@@ -1770,7 +1770,6 @@ public class HeadsetServiceAndStateMachineTest {
HeadsetCallState headsetCallState =
new HeadsetCallState(
0, 0, HeadsetHalConstants.CALL_STATE_INCOMING, TEST_PHONE_NUMBER, 128, "");
- mTestLooper.startAutoDispatch(); // Require as this is waiting unconditionally
mHeadsetService.phoneStateChanged(
headsetCallState.mNumActive,
headsetCallState.mNumHeld,
@@ -1779,7 +1778,6 @@ public class HeadsetServiceAndStateMachineTest {
headsetCallState.mType,
headsetCallState.mName,
false);
- mTestLooper.stopAutoDispatch();
mTestLooper.dispatchAll();
// HeadsetStateMachine completes processing CALL_STATE_CHANGED message
verify(mNativeInterface).phoneStateChange(device, headsetCallState);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java
index 309c7310d2..7261d369bf 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java
@@ -31,8 +31,10 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.BluetoothProfileConnectionInfo;
+import android.os.IBinder;
import android.os.Looper;
import android.os.ParcelUuid;
+import android.os.RemoteException;
import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.filters.MediumTest;
@@ -96,6 +98,9 @@ public class LeAudioBroadcastServiceTest {
@Mock private BassClientService mBassClientService;
@Mock private TbsService mTbsService;
@Mock private MetricsLogger mMetricsLogger;
+ @Mock private IBluetoothLeBroadcastCallback mCallbacks;
+ @Mock private IBinder mBinder;
+
@Spy private LeAudioObjectsFactory mObjectsFactory = LeAudioObjectsFactory.getInstance();
@Spy private ServiceFactory mServiceFactory = new ServiceFactory();
@@ -139,62 +144,13 @@ public class LeAudioBroadcastServiceTest {
private static final List<BluetoothLeAudioCodecConfig> OUTPUT_SELECTABLE_CONFIG_HIGH =
List.of(LC3_48KHZ_CONFIG);
- private boolean mOnBroadcastStartedCalled = false;
- private boolean mOnBroadcastStartFailedCalled = false;
- private boolean mOnBroadcastStoppedCalled = false;
- private boolean mOnBroadcastStopFailedCalled = false;
- private boolean mOnBroadcastUpdatedCalled = false;
- private boolean mOnBroadcastUpdateFailedCalled = false;
- private int mOnBroadcastStartFailedReason = BluetoothStatusCodes.SUCCESS;
-
- private final IBluetoothLeBroadcastCallback mCallbacks =
- new IBluetoothLeBroadcastCallback.Stub() {
- @Override
- public void onBroadcastStarted(int reason, int broadcastId) {
- mOnBroadcastStartedCalled = true;
- }
-
- @Override
- public void onBroadcastStartFailed(int reason) {
- mOnBroadcastStartFailedCalled = true;
- mOnBroadcastStartFailedReason = reason;
- }
-
- @Override
- public void onBroadcastStopped(int reason, int broadcastId) {
- mOnBroadcastStoppedCalled = true;
- }
-
- @Override
- public void onBroadcastStopFailed(int reason) {
- mOnBroadcastStopFailedCalled = true;
- }
-
- @Override
- public void onPlaybackStarted(int reason, int broadcastId) {}
-
- @Override
- public void onPlaybackStopped(int reason, int broadcastId) {}
-
- @Override
- public void onBroadcastUpdated(int reason, int broadcastId) {
- mOnBroadcastUpdatedCalled = true;
- }
-
- @Override
- public void onBroadcastUpdateFailed(int reason, int broadcastId) {
- mOnBroadcastUpdateFailedCalled = true;
- }
-
- @Override
- public void onBroadcastMetadataChanged(
- int broadcastId, BluetoothLeBroadcastMetadata metadata) {}
- };
-
@Before
public void setUp() throws Exception {
mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ doReturn(mBinder).when(mCallbacks).asBinder();
+ doNothing().when(mBinder).linkToDeath(any(), eq(0));
+
// Use spied objects factory
doNothing().when(mTmapGattServer).start(anyInt());
doNothing().when(mTmapGattServer).stop();
@@ -306,8 +262,10 @@ public class LeAudioBroadcastServiceTest {
create_event.valueBool1 = true;
mService.messageFromNative(create_event);
- // Verify if broadcast is auto-started on start
- verify(mLeAudioBroadcasterNativeInterface).startBroadcast(eq(broadcastId));
+ if (!Flags.leaudioBigDependsOnAudioState()) {
+ // Verify if broadcast is auto-started on start
+ verify(mLeAudioBroadcasterNativeInterface).startBroadcast(eq(broadcastId));
+ }
// Notify initial paused state
LeAudioStackEvent state_event =
@@ -326,8 +284,14 @@ public class LeAudioBroadcastServiceTest {
verify(mLeAudioBroadcasterNativeInterface).getBroadcastMetadata(eq(broadcastId));
TestUtils.waitForLooperToFinishScheduledTask(mService.getMainLooper());
- Assert.assertFalse(mOnBroadcastStartFailedCalled);
- Assert.assertTrue(mOnBroadcastStartedCalled);
+ try {
+ verify(mCallbacks, times(0)).onBroadcastStartFailed(anyInt());
+ verify(mCallbacks, times(1))
+ .onBroadcastStarted(
+ eq(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST), anyInt());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
void verifyBroadcastStopped(int broadcastId) {
@@ -361,8 +325,14 @@ public class LeAudioBroadcastServiceTest {
anyLong(),
anyLong(),
eq(0x3)); // STATS_SESSION_SETUP_STATUS_STREAMING
- Assert.assertTrue(mOnBroadcastStoppedCalled);
- Assert.assertFalse(mOnBroadcastStopFailedCalled);
+ try {
+ verify(mCallbacks, times(1))
+ .onBroadcastStopped(
+ eq(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST), anyInt());
+ verify(mCallbacks, times(0)).onBroadcastStopFailed(anyInt());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
@Test
@@ -453,15 +423,19 @@ public class LeAudioBroadcastServiceTest {
eq(0L),
eq(0x4)); // STATS_SESSION_SETUP_STATUS_CREATED_FAILED
- Assert.assertFalse(mOnBroadcastStartedCalled);
- Assert.assertTrue(mOnBroadcastStartFailedCalled);
+ try {
+ verify(mCallbacks, times(0)).onBroadcastStarted(anyInt(), anyInt());
+ verify(mCallbacks, times(1))
+ .onBroadcastStartFailed(eq(BluetoothStatusCodes.ERROR_UNKNOWN));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
@Test
public void testCreateBroadcastTimeout() {
mSetFlagsRule.enableFlags(Flags.FLAG_LEAUDIO_BROADCAST_DESTROY_AFTER_TIMEOUT);
- int broadcastId = 243;
byte[] code = {0x00, 0x01, 0x00, 0x02};
synchronized (mService.mBroadcastCallbacks) {
@@ -477,59 +451,77 @@ public class LeAudioBroadcastServiceTest {
BluetoothLeBroadcastSettings settings = buildBroadcastSettingsFromMetadata(meta, code, 1);
mService.createBroadcast(settings);
- // Test data with only one subgroup
- int[] expectedQualityArray = {settings.getSubgroupSettings().get(0).getPreferredQuality()};
- byte[][] expectedDataArray = {
- settings.getSubgroupSettings().get(0).getContentMetadata().getRawMetadata()
- };
-
- verify(mLeAudioBroadcasterNativeInterface)
- .createBroadcast(
- eq(true),
- eq(TEST_BROADCAST_NAME),
- eq(code),
- eq(settings.getPublicBroadcastMetadata().getRawMetadata()),
- eq(expectedQualityArray),
- eq(expectedDataArray));
-
- // Check if broadcast is started automatically when created
- LeAudioStackEvent create_event =
- new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_CREATED);
- create_event.valueInt1 = broadcastId;
- create_event.valueBool1 = true;
- mService.messageFromNative(create_event);
-
- // Verify if broadcast is auto-started on start
- verify(mLeAudioBroadcasterNativeInterface).startBroadcast(eq(broadcastId));
- TestUtils.waitForLooperToFinishScheduledTask(mService.getMainLooper());
-
- Assert.assertTrue(mOnBroadcastStartedCalled);
-
- // Notify initial paused state
- LeAudioStackEvent state_event =
- new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_STATE);
- state_event.valueInt1 = broadcastId;
- state_event.valueInt2 = LeAudioStackEvent.BROADCAST_STATE_PAUSED;
- mService.messageFromNative(state_event);
+ if (Flags.leaudioBigDependsOnAudioState()) {
+ try {
+ verify(mCallbacks, timeout(CREATE_BROADCAST_TIMEOUT_MS).times(1))
+ .onBroadcastStartFailed(eq(BluetoothStatusCodes.ERROR_TIMEOUT));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ } else {
+ int broadcastId = 243;
+ // Test data with only one subgroup
+ int[] expectedQualityArray = {
+ settings.getSubgroupSettings().get(0).getPreferredQuality()
+ };
+ byte[][] expectedDataArray = {
+ settings.getSubgroupSettings().get(0).getContentMetadata().getRawMetadata()
+ };
- // Check if broadcast is destroyed after timeout
- verify(mLeAudioBroadcasterNativeInterface, timeout(CREATE_BROADCAST_TIMEOUT_MS))
- .destroyBroadcast(eq(broadcastId));
+ verify(mLeAudioBroadcasterNativeInterface)
+ .createBroadcast(
+ eq(true),
+ eq(TEST_BROADCAST_NAME),
+ eq(code),
+ eq(settings.getPublicBroadcastMetadata().getRawMetadata()),
+ eq(expectedQualityArray),
+ eq(expectedDataArray));
+
+ // Check if broadcast is started automatically when created
+ LeAudioStackEvent create_event =
+ new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_CREATED);
+ create_event.valueInt1 = broadcastId;
+ create_event.valueBool1 = true;
+ mService.messageFromNative(create_event);
+
+ // Verify if broadcast is auto-started on start
+ verify(mLeAudioBroadcasterNativeInterface).startBroadcast(eq(broadcastId));
+ TestUtils.waitForLooperToFinishScheduledTask(mService.getMainLooper());
- state_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_DESTROYED);
- state_event.valueInt1 = broadcastId;
- mService.messageFromNative(state_event);
+ try {
+ verify(mCallbacks, times(1))
+ .onBroadcastStarted(
+ eq(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST), anyInt());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
- // Verify broadcast audio session is logged when session failed to stream
- verify(mMetricsLogger)
- .logLeAudioBroadcastAudioSession(
- eq(broadcastId),
- eq(new int[] {0x2}), // STATS_SESSION_AUDIO_QUALITY_HIGH
- eq(0),
- anyLong(),
- anyLong(),
- eq(0L),
- eq(0x5)); // STATS_SESSION_SETUP_STATUS_STREAMING_FAILED
+ // Notify initial paused state
+ LeAudioStackEvent state_event =
+ new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_STATE);
+ state_event.valueInt1 = broadcastId;
+ state_event.valueInt2 = LeAudioStackEvent.BROADCAST_STATE_PAUSED;
+ mService.messageFromNative(state_event);
+
+ // Check if broadcast is destroyed after timeout
+ verify(mLeAudioBroadcasterNativeInterface, timeout(CREATE_BROADCAST_TIMEOUT_MS))
+ .destroyBroadcast(eq(broadcastId));
+
+ state_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_DESTROYED);
+ state_event.valueInt1 = broadcastId;
+ mService.messageFromNative(state_event);
+
+ // Verify broadcast audio session is logged when session failed to stream
+ verify(mMetricsLogger)
+ .logLeAudioBroadcastAudioSession(
+ eq(broadcastId),
+ eq(new int[] {0x2}), // STATS_SESSION_AUDIO_QUALITY_HIGH
+ eq(0),
+ anyLong(),
+ anyLong(),
+ eq(0L),
+ eq(0x5)); // STATS_SESSION_SETUP_STATUS_STREAMING_FAILED
+ }
}
@Test
@@ -649,8 +641,14 @@ public class LeAudioBroadcastServiceTest {
TestUtils.waitForLooperToFinishScheduledTask(mService.getMainLooper());
- Assert.assertFalse(mOnBroadcastStoppedCalled);
- Assert.assertTrue(mOnBroadcastStopFailedCalled);
+ try {
+ verify(mCallbacks, times(0)).onBroadcastStopped(anyInt(), anyInt());
+ verify(mCallbacks, times(1))
+ .onBroadcastStopFailed(
+ eq(BluetoothStatusCodes.ERROR_LE_BROADCAST_INVALID_BROADCAST_ID));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
// Update metadata for non-existing broadcast
BluetoothLeAudioContentMetadata.Builder meta_builder =
@@ -662,8 +660,12 @@ public class LeAudioBroadcastServiceTest {
TestUtils.waitForLooperToFinishScheduledTask(mService.getMainLooper());
- Assert.assertFalse(mOnBroadcastUpdatedCalled);
- Assert.assertTrue(mOnBroadcastUpdateFailedCalled);
+ try {
+ verify(mCallbacks, times(0)).onBroadcastUpdated(anyInt(), anyInt());
+ verify(mCallbacks, times(1)).onBroadcastUpdateFailed(anyInt(), anyInt());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
private BluetoothLeBroadcastSubgroup createBroadcastSubgroup() {
@@ -977,19 +979,21 @@ public class LeAudioBroadcastServiceTest {
TestUtils.waitForLooperToFinishScheduledTask(mService.getMainLooper());
verifyBroadcastStarted(broadcastId, settings);
- mOnBroadcastStartedCalled = false;
- mOnBroadcastStartFailedCalled = false;
+ Mockito.clearInvocations(mCallbacks);
// verify creating another broadcast will fail
mService.createBroadcast(settings);
TestUtils.waitForLooperToFinishScheduledTask(mService.getMainLooper());
- Assert.assertFalse(mOnBroadcastStartedCalled);
- Assert.assertTrue(mOnBroadcastStartFailedCalled);
- Assert.assertEquals(
- BluetoothStatusCodes.ERROR_LOCAL_NOT_ENOUGH_RESOURCES,
- mOnBroadcastStartFailedReason);
+ try {
+ verify(mCallbacks, times(0)).onBroadcastStarted(anyInt(), anyInt());
+ verify(mCallbacks, times(1))
+ .onBroadcastStartFailed(
+ eq(BluetoothStatusCodes.ERROR_LOCAL_NOT_ENOUGH_RESOURCES));
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
private void prepareHandoverStreamingBroadcast(int groupId, int broadcastId, byte[] code) {
@@ -1083,9 +1087,6 @@ public class LeAudioBroadcastServiceTest {
create_event.valueBool1 = true;
mService.messageFromNative(create_event);
- /* Verify if broadcast is auto-started on start */
- verify(mLeAudioBroadcasterNativeInterface).startBroadcast(eq(broadcastId));
-
/* Switch to active streaming */
create_event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_BROADCAST_STATE);
create_event.device = mBroadcastDevice;
@@ -1108,6 +1109,8 @@ public class LeAudioBroadcastServiceTest {
/* Imitate setting device in call */
mService.setInCall(true);
+ Assert.assertTrue(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
+
/* Check if broadcast is paused by InCall handling */
verify(mLeAudioBroadcasterNativeInterface).pauseBroadcast(eq(broadcastId));
@@ -1155,8 +1158,8 @@ public class LeAudioBroadcastServiceTest {
.handleBluetoothActiveDeviceChanged(
eq(mBroadcastDevice), eq(null), any(BluetoothProfileConnectionInfo.class));
- /* Verify if broadcast is auto-started on start */
- verify(mLeAudioBroadcasterNativeInterface, times(2)).startBroadcast(eq(broadcastId));
+ /* Verify if broadcast triggers transition */
+ Assert.assertFalse(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
}
@Test
@@ -1172,6 +1175,8 @@ public class LeAudioBroadcastServiceTest {
/* Imitate setting device in call */
mService.handleAudioModeChange(AudioManager.MODE_IN_CALL);
+ Assert.assertTrue(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
+
/* Check if broadcast is paused by AudioMode handling */
verify(mLeAudioBroadcasterNativeInterface).pauseBroadcast(eq(broadcastId));
@@ -1227,8 +1232,13 @@ public class LeAudioBroadcastServiceTest {
.handleBluetoothActiveDeviceChanged(
eq(mBroadcastDevice), eq(null), any(BluetoothProfileConnectionInfo.class));
- /* Verify if broadcast is auto-started on start */
- verify(mLeAudioBroadcasterNativeInterface, times(2)).startBroadcast(eq(broadcastId));
+ if (Flags.leaudioBigDependsOnAudioState()) {
+ /* Verify if broadcast triggers transition */
+ Assert.assertFalse(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
+ } else {
+ /* Verify if broadcast is auto-started on start */
+ verify(mLeAudioBroadcasterNativeInterface, times(2)).startBroadcast(eq(broadcastId));
+ }
}
@Test
@@ -1239,8 +1249,10 @@ public class LeAudioBroadcastServiceTest {
prepareHandoverStreamingBroadcast(groupId, broadcastId, code);
- /* Verify if broadcast is auto-started on start */
- verify(mLeAudioBroadcasterNativeInterface).startBroadcast(eq(broadcastId));
+ if (!Flags.leaudioBigDependsOnAudioState()) {
+ /* Verify if broadcast is auto-started on start */
+ verify(mLeAudioBroadcasterNativeInterface).startBroadcast(eq(broadcastId));
+ }
/* Imitate group change request by Bluetooth Sink HAL resume request */
LeAudioStackEvent create_event =
@@ -1249,6 +1261,8 @@ public class LeAudioBroadcastServiceTest {
create_event.valueInt2 = LeAudioStackEvent.STATUS_LOCAL_STREAM_REQUESTED;
mService.messageFromNative(create_event);
+ Assert.assertTrue(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
+
/* Check if broadcast is paused triggered by group change request */
verify(mLeAudioBroadcasterNativeInterface).pauseBroadcast(eq(broadcastId));
@@ -1297,8 +1311,13 @@ public class LeAudioBroadcastServiceTest {
.handleBluetoothActiveDeviceChanged(
eq(mBroadcastDevice), eq(null), any(BluetoothProfileConnectionInfo.class));
- /* Verify if broadcast is auto-started on start */
- verify(mLeAudioBroadcasterNativeInterface, times(2)).startBroadcast(eq(broadcastId));
+ if (Flags.leaudioBigDependsOnAudioState()) {
+ /* Verify if broadcast triggers transition */
+ Assert.assertFalse(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
+ } else {
+ /* Verify if broadcast is auto-started on start */
+ verify(mLeAudioBroadcasterNativeInterface, times(2)).startBroadcast(eq(broadcastId));
+ }
}
@Test
@@ -1321,6 +1340,8 @@ public class LeAudioBroadcastServiceTest {
/* Imitate setting device in call */
mService.setInCall(true);
+ Assert.assertTrue(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
+
/* Broadcast already paused, not call pause again by InCall handling */
verify(mLeAudioBroadcasterNativeInterface, never()).pauseBroadcast(eq(broadcastId));
@@ -1362,8 +1383,8 @@ public class LeAudioBroadcastServiceTest {
.handleBluetoothActiveDeviceChanged(
eq(mBroadcastDevice), eq(null), any(BluetoothProfileConnectionInfo.class));
- /* Verify if broadcast is auto-started on start */
- verify(mLeAudioBroadcasterNativeInterface, times(2)).startBroadcast(eq(broadcastId));
+ /* Verify if broadcast triggers transition */
+ Assert.assertFalse(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
}
@Test
@@ -1386,6 +1407,8 @@ public class LeAudioBroadcastServiceTest {
/* Imitate setting device in call */
mService.handleAudioModeChange(AudioManager.MODE_IN_CALL);
+ Assert.assertTrue(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
+
/* Broadcast already paused, not call pause again by AudioMode handling */
verify(mLeAudioBroadcasterNativeInterface, never()).pauseBroadcast(eq(broadcastId));
@@ -1435,8 +1458,8 @@ public class LeAudioBroadcastServiceTest {
.handleBluetoothActiveDeviceChanged(
eq(mBroadcastDevice), eq(null), any(BluetoothProfileConnectionInfo.class));
- /* Verify if broadcast is auto-started on start */
- verify(mLeAudioBroadcasterNativeInterface, times(2)).startBroadcast(eq(broadcastId));
+ /* Verify if broadcast triggers transition */
+ Assert.assertFalse(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
}
@Test
@@ -1462,6 +1485,8 @@ public class LeAudioBroadcastServiceTest {
create_event.valueInt2 = LeAudioStackEvent.STATUS_LOCAL_STREAM_REQUESTED;
mService.messageFromNative(create_event);
+ Assert.assertTrue(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
+
/* Broadcast already paused, not call pause again by group change request */
verify(mLeAudioBroadcasterNativeInterface, never()).pauseBroadcast(eq(broadcastId));
@@ -1503,9 +1528,8 @@ public class LeAudioBroadcastServiceTest {
verify(mAudioManager)
.handleBluetoothActiveDeviceChanged(
eq(mBroadcastDevice), eq(null), any(BluetoothProfileConnectionInfo.class));
-
- /* Verify if broadcast is auto-started on start */
- verify(mLeAudioBroadcasterNativeInterface, times(2)).startBroadcast(eq(broadcastId));
+ /* Verify if broadcast triggers transition */
+ Assert.assertFalse(mService.mBroadcastIdDeactivatedForUnicastTransition.isPresent());
}
@Test
diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_scan/TransitionalScanHelperTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_scan/TransitionalScanHelperTest.java
index f49529c65e..3176c78f6a 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/le_scan/TransitionalScanHelperTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/le_scan/TransitionalScanHelperTest.java
@@ -291,7 +291,6 @@ public class TransitionalScanHelperTest {
@Test
public void onScanResult_remoteException_clientDied() throws Exception {
- mSetFlagsRule.enableFlags(Flags.FLAG_LE_SCAN_FIX_REMOTE_EXCEPTION);
int scannerId = 1;
int eventType = 0;
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java
index e8f65e3966..042666d321 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java
@@ -2156,9 +2156,7 @@ public class BluetoothMapContentObserverTest {
// This mock sets type to MMS
doReturn(4)
.when(mIntent)
- .getIntExtra(
- BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_MSG_TYPE,
- TYPE.NONE.ordinal());
+ .getIntExtra(eq(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_MSG_TYPE), anyInt());
mObserver.actionMessageSentDisconnected(mContext, mIntent, 1);
@@ -2177,9 +2175,7 @@ public class BluetoothMapContentObserverTest {
// This mock sets type to Email
doReturn(1)
.when(mIntent)
- .getIntExtra(
- BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_MSG_TYPE,
- TYPE.NONE.ordinal());
+ .getIntExtra(eq(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_MSG_TYPE), anyInt());
clearInvocations(mContext);
mObserver.actionMessageSentDisconnected(mContext, mIntent, Activity.RESULT_FIRST_USER);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java
index e55117a037..a43c63d033 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapbMessageSmsTest.java
@@ -16,9 +16,12 @@
package com.android.bluetooth.map;
+import static android.content.pm.PackageManager.FEATURE_TELEPHONY_MESSAGING;
+
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.telephony.SmsManager;
import androidx.test.InstrumentationRegistry;
@@ -50,7 +53,11 @@ public class BluetoothMapbMessageSmsTest {
@Before
public void setUp() throws Exception {
// Do not run test if sms is not supported
+ PackageManager packageManager =
+ InstrumentationRegistry.getTargetContext().getPackageManager();
+ Assume.assumeTrue(packageManager.isPackageAvailable(FEATURE_TELEPHONY_MESSAGING));
Assume.assumeTrue(mSmsManager.isImsSmsSupported());
+
mTargetContext = InstrumentationRegistry.getTargetContext();
TEST_SMS_BODY_PDUS =
BluetoothMapSmsPdu.getSubmitPdus(mTargetContext, TEST_MESSAGE, TEST_ADDRESS);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceCleanupTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceCleanupTest.java
index d2db49fbc5..2183c19347 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceCleanupTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppServiceCleanupTest.java
@@ -46,7 +46,7 @@ public class BluetoothOppServiceCleanupTest {
@Test
@UiThreadTest
- public void testStopAndCleanup() {
+ public void testStopAndCleanup() throws Exception {
AdapterService adapterService = new AdapterService(mTargetContext);
// Don't need to disable again since it will be handled in OppService.stop
@@ -58,8 +58,9 @@ public class BluetoothOppServiceCleanupTest {
mTargetContext.getContentResolver().insert(BluetoothShare.CONTENT_URI, values);
}
+ BluetoothOppService service = null;
try {
- BluetoothOppService service = new BluetoothOppService(adapterService);
+ service = new BluetoothOppService(adapterService);
service.start();
service.setAvailable(true);
@@ -67,6 +68,12 @@ public class BluetoothOppServiceCleanupTest {
service.stop();
service.cleanup();
} finally {
+ if (service != null) {
+ Thread updateNotificationThread = service.mNotifier.mUpdateNotificationThread;
+ if (updateNotificationThread != null) {
+ updateNotificationThread.join();
+ }
+ }
mTargetContext.getContentResolver().delete(BluetoothShare.CONTENT_URI, null, null);
}
}
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 22affe39cf..4b5bd23465 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
@@ -107,6 +107,10 @@ public class BluetoothOppServiceTest {
BluetoothOppService service = mService;
if (service != null) {
service.mUpdateThread = null;
+ Thread updateNotificationThread = service.mNotifier.mUpdateNotificationThread;
+ if (updateNotificationThread != null) {
+ updateNotificationThread.join();
+ }
}
BluetoothMethodProxy.setInstanceForTesting(null);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java
index 2f734f585f..9b0aa48c62 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlNativeInterfaceTest.java
@@ -21,6 +21,8 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.bluetooth.BluetoothProfile;
+
import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
@@ -55,7 +57,7 @@ public class VolumeControlNativeInterfaceTest {
@Test
public void onConnectionStateChanged() {
- int state = VolumeControlStackEvent.CONNECTION_STATE_CONNECTED;
+ int state = BluetoothProfile.STATE_CONNECTED;
byte[] address = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
mNativeInterface.onConnectionStateChanged(state, address);
diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java
index 22ec653e36..c753899100 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlServiceTest.java
@@ -17,9 +17,32 @@
package com.android.bluetooth.vc;
+import static android.bluetooth.BluetoothDevice.BOND_BONDED;
+import static android.bluetooth.BluetoothDevice.BOND_BONDING;
+import static android.bluetooth.BluetoothDevice.BOND_NONE;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTING;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING;
import static android.bluetooth.IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID;
-import static org.mockito.Mockito.*;
+import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction;
+import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
@@ -28,20 +51,16 @@ import android.bluetooth.BluetoothUuid;
import android.bluetooth.BluetoothVolumeControl;
import android.bluetooth.IBluetoothVolumeControlCallback;
import android.content.AttributionSource;
-import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Binder;
-import android.os.Looper;
import android.os.ParcelUuid;
+import android.os.test.TestLooper;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.filters.MediumTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.rule.ServiceTestRule;
import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.TestUtils;
@@ -53,46 +72,31 @@ import com.android.bluetooth.csip.CsipSetCoordinatorService;
import com.android.bluetooth.flags.Flags;
import com.android.bluetooth.le_audio.LeAudioService;
+import org.hamcrest.Matcher;
+import org.hamcrest.core.AllOf;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
+import org.mockito.hamcrest.MockitoHamcrest;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
-import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.IntStream;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class VolumeControlServiceTest {
- private BluetoothAdapter mAdapter;
- private AttributionSource mAttributionSource;
- private Context mTargetContext;
- private VolumeControlService mService;
- private VolumeControlService.BluetoothVolumeControlBinder mServiceBinder;
- private BluetoothDevice mDevice;
- private BluetoothDevice mDeviceTwo;
- private HashMap<BluetoothDevice, LinkedBlockingQueue<Intent>> mDeviceQueueMap;
- private static final int TIMEOUT_MS = 1000;
- private static final int BT_LE_AUDIO_MAX_VOL = 255;
- private static final int MEDIA_MIN_VOL = 0;
- private static final int MEDIA_MAX_VOL = 25;
- private static final int CALL_MIN_VOL = 1;
- private static final int CALL_MAX_VOL = 8;
- private static final int TEST_GROUP_ID = 1;
-
- private BroadcastReceiver mVolumeControlIntentReceiver;
-
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+ @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Mock private AdapterService mAdapterService;
@Mock private BassClientService mBassClientService;
@@ -103,22 +107,41 @@ public class VolumeControlServiceTest {
@Mock private ServiceFactory mServiceFactory;
@Mock private CsipSetCoordinatorService mCsipService;
- @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule();
- @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+ private static final int BT_LE_AUDIO_MAX_VOL = 255;
+ private static final int MEDIA_MIN_VOL = 0;
+ private static final int MEDIA_MAX_VOL = 25;
+ private static final int CALL_MIN_VOL = 1;
+ private static final int CALL_MAX_VOL = 8;
+ private static final int TEST_GROUP_ID = 1;
+
+ private final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
+ private final BluetoothDevice mDevice = TestUtils.getTestDevice(mAdapter, 134);
+ private final BluetoothDevice mDeviceTwo = TestUtils.getTestDevice(mAdapter, 231);
+
+ private AttributionSource mAttributionSource;
+ private VolumeControlService mService;
+ private VolumeControlService.BluetoothVolumeControlBinder mBinder;
+ private InOrder mInOrder;
+ private TestLooper mLooper;
@Before
- public void setUp() throws Exception {
- mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ public void setUp() {
+ doReturn(true).when(mNativeInterface).connectVolumeControl(any());
+ doReturn(true).when(mNativeInterface).disconnectVolumeControl(any());
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
+ doReturn(CONNECTION_POLICY_ALLOWED)
+ .when(mDatabaseManager)
+ .getProfileConnectionPolicy(any(), anyInt());
- TestUtils.setAdapterService(mAdapterService);
doReturn(mDatabaseManager).when(mAdapterService).getDatabase();
+ doReturn(BOND_BONDED).when(mAdapterService).getBondState(any());
+ doReturn(new ParcelUuid[] {BluetoothUuid.VOLUME_CONTROL})
+ .when(mAdapterService)
+ .getRemoteUuids(any(BluetoothDevice.class));
- mAdapter = BluetoothAdapter.getDefaultAdapter();
- mAttributionSource = mAdapter.getAttributionSource();
+ doReturn(mCsipService).when(mServiceFactory).getCsipSetCoordinatorService();
+ doReturn(mLeAudioService).when(mServiceFactory).getLeAudioService();
+ doReturn(mBassClientService).when(mServiceFactory).getBassClientService();
doReturn(MEDIA_MIN_VOL)
.when(mAudioManager)
@@ -132,432 +155,243 @@ public class VolumeControlServiceTest {
doReturn(CALL_MAX_VOL)
.when(mAudioManager)
.getStreamMaxVolume(eq(AudioManager.STREAM_VOICE_CALL));
+ TestUtils.mockGetSystemService(
+ mAdapterService, Context.AUDIO_SERVICE, AudioManager.class, mAudioManager);
+
+ mInOrder = inOrder(mAdapterService);
+ mLooper = new TestLooper();
- VolumeControlNativeInterface.setInstance(mNativeInterface);
- mService = new VolumeControlService(mTargetContext);
- mService.start();
+ mAttributionSource = mAdapter.getAttributionSource();
+ mService = new VolumeControlService(mAdapterService, mLooper.getLooper(), mNativeInterface);
mService.setAvailable(true);
- mService.mAudioManager = mAudioManager;
mService.mFactory = mServiceFactory;
- mServiceBinder = (VolumeControlService.BluetoothVolumeControlBinder) mService.initBinder();
-
- doReturn(mCsipService).when(mServiceFactory).getCsipSetCoordinatorService();
- doReturn(mLeAudioService).when(mServiceFactory).getLeAudioService();
- doReturn(mBassClientService).when(mServiceFactory).getBassClientService();
-
- // Override the timeout value to speed up the test
- VolumeControlStateMachine.sConnectTimeoutMs = TIMEOUT_MS; // 1s
-
- // Set up the Connection State Changed receiver
- IntentFilter filter = new IntentFilter();
- filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
- filter.addAction(BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED);
-
- mVolumeControlIntentReceiver = new VolumeControlIntentReceiver();
- mTargetContext.registerReceiver(mVolumeControlIntentReceiver, filter);
-
- // Get a device for testing
- mDevice = TestUtils.getTestDevice(mAdapter, 0);
- mDeviceTwo = TestUtils.getTestDevice(mAdapter, 1);
- mDeviceQueueMap = new HashMap<>();
- mDeviceQueueMap.put(mDevice, new LinkedBlockingQueue<>());
- mDeviceQueueMap.put(mDeviceTwo, new LinkedBlockingQueue<>());
- doReturn(BluetoothDevice.BOND_BONDED)
- .when(mAdapterService)
- .getBondState(any(BluetoothDevice.class));
- doReturn(new ParcelUuid[] {BluetoothUuid.VOLUME_CONTROL})
- .when(mAdapterService)
- .getRemoteUuids(any(BluetoothDevice.class));
+ mBinder = (VolumeControlService.BluetoothVolumeControlBinder) mService.initBinder();
}
@After
- public void tearDown() throws Exception {
- if (mService == null) {
- return;
- }
-
+ public void tearDown() {
+ assertThat(mLooper.nextMessage()).isNull();
mService.stop();
- VolumeControlNativeInterface.setInstance(null);
- mTargetContext.unregisterReceiver(mVolumeControlIntentReceiver);
- mDeviceQueueMap.clear();
- TestUtils.clearAdapterService(mAdapterService);
- reset(mAudioManager);
- }
-
- private class VolumeControlIntentReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- try {
- BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- Assert.assertNotNull(device);
- LinkedBlockingQueue<Intent> queue = mDeviceQueueMap.get(device);
- Assert.assertNotNull(queue);
- queue.put(intent);
- } catch (InterruptedException e) {
- Assert.fail("Cannot add Intent to the Connection State queue: " + e.getMessage());
- }
- }
- }
-
- private void verifyConnectionStateIntent(
- int timeoutMs, BluetoothDevice device, int newState, int prevState) {
- Intent intent = TestUtils.waitForIntent(timeoutMs, mDeviceQueueMap.get(device));
- Assert.assertNotNull(intent);
- Assert.assertEquals(
- BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED, intent.getAction());
- Assert.assertEquals(device, intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
- Assert.assertEquals(newState, intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
- Assert.assertEquals(
- prevState, intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1));
- }
-
- private void verifyNoConnectionStateIntent(int timeoutMs, BluetoothDevice device) {
- Intent intent = TestUtils.waitForNoIntent(timeoutMs, mDeviceQueueMap.get(device));
- Assert.assertNull(intent);
+ mLooper.dispatchAll();
+ assertThat(VolumeControlService.getVolumeControlService()).isNull();
}
- /** Test getting VolumeControl Service: getVolumeControlService() */
@Test
- public void testGetVolumeControlService() {
- Assert.assertEquals(mService, VolumeControlService.getVolumeControlService());
+ public void getVolumeControlService() {
+ assertThat(VolumeControlService.getVolumeControlService()).isEqualTo(mService);
}
- /** Test stop VolumeControl Service */
@Test
- public void testStopVolumeControlService() throws Exception {
- // Prepare: connect
- connectDevice(mDevice);
- // VolumeControl Service is already running: test stop().
- // Note: must be done on the main thread
- InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::stop);
- // Try to restart the service. Note: must be done on the main thread
- InstrumentationRegistry.getInstrumentation().runOnMainSync(mService::start);
- }
-
- /** Test get/set policy for BluetoothDevice */
- @Test
- public void testGetSetPolicy() {
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
- Assert.assertEquals(
- "Initial device policy",
- BluetoothProfile.CONNECTION_POLICY_UNKNOWN,
- mService.getConnectionPolicy(mDevice));
-
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
- Assert.assertEquals(
- "Setting device policy to POLICY_FORBIDDEN",
- BluetoothProfile.CONNECTION_POLICY_FORBIDDEN,
- mService.getConnectionPolicy(mDevice));
-
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- Assert.assertEquals(
- "Setting device policy to POLICY_ALLOWED",
- BluetoothProfile.CONNECTION_POLICY_ALLOWED,
- mService.getConnectionPolicy(mDevice));
+ public void getConnectionPolicy() {
+ for (int policy :
+ List.of(
+ CONNECTION_POLICY_UNKNOWN,
+ CONNECTION_POLICY_FORBIDDEN,
+ CONNECTION_POLICY_ALLOWED)) {
+ doReturn(policy).when(mDatabaseManager).getProfileConnectionPolicy(any(), anyInt());
+ assertThat(mService.getConnectionPolicy(mDevice)).isEqualTo(policy);
+ }
}
- /** Test if getProfileConnectionPolicy works after the service is stopped. */
@Test
- public void testGetPolicyAfterStopped() throws Exception {
- mService.stop();
- when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
- int policy = mServiceBinder.getConnectionPolicy(mDevice, mAttributionSource);
- Assert.assertEquals(
- "Initial device policy", BluetoothProfile.CONNECTION_POLICY_UNKNOWN, policy);
+ public void canConnect_whenNotBonded_returnFalse() {
+ int badPolicyValue = 1024;
+ int badBondState = 42;
+ for (int bondState : List.of(BOND_NONE, BOND_BONDING, badBondState)) {
+ for (int policy :
+ List.of(
+ CONNECTION_POLICY_UNKNOWN,
+ CONNECTION_POLICY_FORBIDDEN,
+ CONNECTION_POLICY_ALLOWED,
+ badPolicyValue)) {
+ doReturn(bondState).when(mAdapterService).getBondState(any());
+ doReturn(policy).when(mDatabaseManager).getProfileConnectionPolicy(any(), anyInt());
+ assertThat(mService.okToConnect(mDevice)).isEqualTo(false);
+ }
+ }
}
- /** Test okToConnect method using various test cases */
@Test
- public void testOkToConnect() {
+ public void canConnect_whenBonded() {
int badPolicyValue = 1024;
- int badBondState = 42;
- testOkToConnectCase(
- mDevice,
- BluetoothDevice.BOND_NONE,
- BluetoothProfile.CONNECTION_POLICY_UNKNOWN,
- false);
- testOkToConnectCase(
- mDevice,
- BluetoothDevice.BOND_NONE,
- BluetoothProfile.CONNECTION_POLICY_FORBIDDEN,
- false);
- testOkToConnectCase(
- mDevice,
- BluetoothDevice.BOND_NONE,
- BluetoothProfile.CONNECTION_POLICY_ALLOWED,
- false);
- testOkToConnectCase(mDevice, BluetoothDevice.BOND_NONE, badPolicyValue, false);
- testOkToConnectCase(
- mDevice,
- BluetoothDevice.BOND_BONDING,
- BluetoothProfile.CONNECTION_POLICY_UNKNOWN,
- false);
- testOkToConnectCase(
- mDevice,
- BluetoothDevice.BOND_BONDING,
- BluetoothProfile.CONNECTION_POLICY_FORBIDDEN,
- false);
- testOkToConnectCase(
- mDevice,
- BluetoothDevice.BOND_BONDING,
- BluetoothProfile.CONNECTION_POLICY_ALLOWED,
- false);
- testOkToConnectCase(mDevice, BluetoothDevice.BOND_BONDING, badPolicyValue, false);
- testOkToConnectCase(
- mDevice,
- BluetoothDevice.BOND_BONDED,
- BluetoothProfile.CONNECTION_POLICY_UNKNOWN,
- true);
- testOkToConnectCase(
- mDevice,
- BluetoothDevice.BOND_BONDED,
- BluetoothProfile.CONNECTION_POLICY_FORBIDDEN,
- false);
- testOkToConnectCase(
- mDevice,
- BluetoothDevice.BOND_BONDED,
- BluetoothProfile.CONNECTION_POLICY_ALLOWED,
- true);
- testOkToConnectCase(mDevice, BluetoothDevice.BOND_BONDED, badPolicyValue, false);
- testOkToConnectCase(
- mDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, false);
- testOkToConnectCase(
- mDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN, false);
- testOkToConnectCase(
- mDevice, badBondState, BluetoothProfile.CONNECTION_POLICY_ALLOWED, false);
- testOkToConnectCase(mDevice, badBondState, badPolicyValue, false);
+ doReturn(BOND_BONDED).when(mAdapterService).getBondState(any());
+
+ for (int policy : List.of(CONNECTION_POLICY_FORBIDDEN, badPolicyValue)) {
+ doReturn(policy).when(mDatabaseManager).getProfileConnectionPolicy(any(), anyInt());
+ assertThat(mService.okToConnect(mDevice)).isEqualTo(false);
+ }
+ for (int policy : List.of(CONNECTION_POLICY_UNKNOWN, CONNECTION_POLICY_ALLOWED)) {
+ doReturn(policy).when(mDatabaseManager).getProfileConnectionPolicy(any(), anyInt());
+ assertThat(mService.okToConnect(mDevice)).isEqualTo(true);
+ }
}
- /**
- * Test that an outgoing connection to device that does not have Volume Control UUID is rejected
- */
@Test
- public void testOutgoingConnectMissingVolumeControlUuid() {
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
+ public void connectToDevice_whenUuidIsMissing_returnFalse() {
// Return No UUID
doReturn(new ParcelUuid[] {})
.when(mAdapterService)
.getRemoteUuids(any(BluetoothDevice.class));
- // Send a connect request
- Assert.assertFalse("Connect expected to fail", mService.connect(mDevice));
+ assertThat(mService.connect(mDevice)).isFalse();
+ }
+
+ @Test
+ public void disconnect_whenConnecting_isDisconnectedWithBroadcast() {
+ assertThat(mService.connect(mDevice)).isTrue();
+ mLooper.dispatchAll();
+ verifyConnectionStateIntent(mDevice, STATE_CONNECTING, STATE_DISCONNECTED);
+
+ assertThat(mService.disconnect(mDevice)).isTrue();
+ mLooper.dispatchAll();
+ verifyConnectionStateIntent(mDevice, STATE_DISCONNECTED, STATE_CONNECTING);
}
- /** Test that an outgoing connection to device that have Volume Control UUID is successful */
@Test
- public void testOutgoingConnectDisconnectExistingVolumeControlUuid() throws Exception {
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
+ public void connectToDevice_whenPolicyForbid_returnFalse() {
when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
+ .thenReturn(CONNECTION_POLICY_FORBIDDEN);
- // Return Volume Control UUID
- doReturn(new ParcelUuid[] {BluetoothUuid.VOLUME_CONTROL})
- .when(mAdapterService)
- .getRemoteUuids(any(BluetoothDevice.class));
+ assertThat(mService.connect(mDevice)).isFalse();
+ }
- // Send a connect request
- Assert.assertTrue("Connect expected to succeed", mService.connect(mDevice));
+ @Test
+ public void outgoingConnect_whenTimeOut_isDisconnected() {
+ assertThat(mService.connect(mDevice)).isTrue();
+ mLooper.dispatchAll();
- // Verify the connection state broadcast, and that we are in Connecting state
- verifyConnectionStateIntent(
- TIMEOUT_MS,
- mDevice,
- BluetoothProfile.STATE_CONNECTING,
- BluetoothProfile.STATE_DISCONNECTED);
+ verifyConnectionStateIntent(mDevice, STATE_CONNECTING, STATE_DISCONNECTED);
- // Send a disconnect request
- Assert.assertTrue("Disconnect expected to succeed", mService.disconnect(mDevice));
+ mLooper.moveTimeForward(VolumeControlStateMachine.CONNECT_TIMEOUT.toMillis());
+ mLooper.dispatchAll();
- // Verify the connection state broadcast, and that we are in Connecting state
- verifyConnectionStateIntent(
- TIMEOUT_MS,
- mDevice,
- BluetoothProfile.STATE_DISCONNECTED,
- BluetoothProfile.STATE_CONNECTING);
+ verifyConnectionStateIntent(mDevice, STATE_DISCONNECTED, STATE_CONNECTING);
}
- /** Test that an outgoing connection to device with POLICY_FORBIDDEN is rejected */
@Test
- public void testOutgoingConnectPolicyForbidden() {
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
- // Set the device policy to POLICY_FORBIDDEN so connect() should fail
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
-
- // Send a connect request
- Assert.assertFalse("Connect expected to fail", mService.connect(mDevice));
+ public void incomingConnecting_whenNoDevice_createStateMachine() {
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTING, STATE_DISCONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
}
- /** Test that an outgoing connection times out */
@Test
- public void testOutgoingConnectTimeout() throws Exception {
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
+ public void incomingDisconnect_whenConnectingDevice_keepStateMachine() {
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTING, STATE_DISCONNECTED);
- // Send a connect request
- Assert.assertTrue("Connect failed", mService.connect(mDevice));
-
- // Verify the connection state broadcast, and that we are in Connecting state
- verifyConnectionStateIntent(
- TIMEOUT_MS,
- mDevice,
- BluetoothProfile.STATE_CONNECTING,
- BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice));
-
- // Verify the connection state broadcast, and that we are in Disconnected state
- verifyConnectionStateIntent(
- VolumeControlStateMachine.sConnectTimeoutMs * 2,
- mDevice,
- BluetoothProfile.STATE_DISCONNECTED,
- BluetoothProfile.STATE_CONNECTING);
-
- int state = mServiceBinder.getConnectionState(mDevice, mAttributionSource);
- Assert.assertEquals(BluetoothProfile.STATE_DISCONNECTED, state);
+ generateConnectionMessageFromNative(mDevice, STATE_DISCONNECTED, STATE_CONNECTING);
+ assertThat(mService.getDevices()).contains(mDevice);
}
- /**
- * Test that only CONNECTION_STATE_CONNECTED or CONNECTION_STATE_CONNECTING Volume Control stack
- * events will create a state machine.
- */
@Test
- public void testCreateStateMachineStackEvents() {
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
+ public void incomingConnect_whenNoDevice_createStateMachine() {
+ // Theoretically impossible case
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
+ }
- // stack event: CONNECTION_STATE_CONNECTING - state machine should be created
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ @Test
+ public void incomingDisconnect_whenConnectedDevice_keepStateMachine() {
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
- // stack event: CONNECTION_STATE_DISCONNECTED - state machine should be removed
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING);
- Assert.assertEquals(
- BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
- mService.bondStateChanged(mDevice, BluetoothDevice.BOND_NONE);
- Assert.assertFalse(mService.getDevices().contains(mDevice));
-
- // stack event: CONNECTION_STATE_CONNECTED - state machine should be created
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ generateConnectionMessageFromNative(mDevice, STATE_DISCONNECTED, STATE_CONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_DISCONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
+ }
- // stack event: CONNECTION_STATE_DISCONNECTED - state machine should be removed
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
- mService.bondStateChanged(mDevice, BluetoothDevice.BOND_NONE);
- Assert.assertFalse(mService.getDevices().contains(mDevice));
-
- // stack event: CONNECTION_STATE_DISCONNECTING - state machine should not be created
- generateUnexpectedConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_DISCONNECTING);
- Assert.assertEquals(
- BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice));
- Assert.assertFalse(mService.getDevices().contains(mDevice));
-
- // stack event: CONNECTION_STATE_DISCONNECTED - state machine should not be created
- generateUnexpectedConnectionMessageFromNative(mDevice, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice));
- Assert.assertFalse(mService.getDevices().contains(mDevice));
+ @Test
+ public void incomingDisconnecting_whenNoDevice_noStateMachine() {
+ generateUnexpectedConnectionMessageFromNative(mDevice, STATE_DISCONNECTING);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_DISCONNECTED);
+ assertThat(mService.getDevices()).doesNotContain(mDevice);
}
- /**
- * Test that a CONNECTION_STATE_DISCONNECTED Volume Control stack event will remove the state
- * machine only if the device is unbond.
- */
@Test
- public void testDeleteStateMachineDisconnectEvents() {
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(mDevice, BluetoothProfile.VOLUME_CONTROL))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
+ public void incomingDisconnect_whenNoDevice_noStateMachine() {
+ generateUnexpectedConnectionMessageFromNative(mDevice, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_DISCONNECTED);
+ assertThat(mService.getDevices()).doesNotContain(mDevice);
+ }
- // stack event: CONNECTION_STATE_CONNECTING - state machine should be created
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ @Test
+ public void unBondDevice_whenConnecting_keepStateMachine() {
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTING, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTING);
+ assertThat(mService.getDevices()).contains(mDevice);
+
+ mService.bondStateChanged(mDevice, BOND_NONE);
+ assertThat(mService.getDevices()).contains(mDevice);
+ assertThat(mLooper.nextMessage().what)
+ .isEqualTo(VolumeControlStateMachine.MESSAGE_DISCONNECT);
+ }
- // stack event: CONNECTION_STATE_DISCONNECTED - state machine is not removed
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING);
- Assert.assertEquals(
- BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ @Test
+ public void unBondDevice_whenConnected_keepStateMachine() {
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTING, STATE_DISCONNECTED);
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_CONNECTING);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
+
+ mService.bondStateChanged(mDevice, BOND_NONE);
+ assertThat(mService.getDevices()).contains(mDevice);
+ assertThat(mLooper.nextMessage().what)
+ .isEqualTo(VolumeControlStateMachine.MESSAGE_DISCONNECT);
+ }
- // stack event: CONNECTION_STATE_CONNECTING - state machine remains
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ @Test
+ public void unBondDevice_whenDisconnecting_keepStateMachine() {
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTING, STATE_DISCONNECTED);
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_CONNECTING);
+ generateConnectionMessageFromNative(mDevice, STATE_DISCONNECTING, STATE_CONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_DISCONNECTING);
+ assertThat(mService.getDevices()).contains(mDevice);
+
+ mService.bondStateChanged(mDevice, BOND_NONE);
+ assertThat(mService.getDevices()).contains(mDevice);
+ assertThat(mLooper.nextMessage().what)
+ .isEqualTo(VolumeControlStateMachine.MESSAGE_DISCONNECT);
+ }
- // device bond state marked as unbond - state machine is not removed
- doReturn(BluetoothDevice.BOND_NONE)
- .when(mAdapterService)
- .getBondState(any(BluetoothDevice.class));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ @Test
+ public void unBondDevice_whenDisconnected_removeStateMachine() {
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTING, STATE_DISCONNECTED);
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_CONNECTING);
+ generateConnectionMessageFromNative(mDevice, STATE_DISCONNECTING, STATE_CONNECTED);
+ generateConnectionMessageFromNative(mDevice, STATE_DISCONNECTED, STATE_DISCONNECTING);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_DISCONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
+
+ mService.bondStateChanged(mDevice, BOND_NONE);
+ mLooper.dispatchAll();
+ assertThat(mService.getDevices()).doesNotContain(mDevice);
+ }
- // stack event: CONNECTION_STATE_DISCONNECTED - state machine is removed
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_CONNECTING);
- Assert.assertEquals(
- BluetoothProfile.STATE_DISCONNECTED, mService.getConnectionState(mDevice));
- Assert.assertFalse(mService.getDevices().contains(mDevice));
+ @Test
+ public void disconnect_whenBonded_keepStateMachine() {
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTING, STATE_DISCONNECTED);
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_CONNECTING);
+ generateConnectionMessageFromNative(mDevice, STATE_DISCONNECTING, STATE_CONNECTED);
+ generateConnectionMessageFromNative(mDevice, STATE_DISCONNECTED, STATE_DISCONNECTING);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_DISCONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
}
- /** Test that various Volume Control stack events will broadcast related states. */
@Test
- public void testVolumeControlStackEvents() {
- int group_id = -1;
- int volume = 6;
- int flags = 0;
- boolean mute = false;
- boolean isAutonomous = false;
+ public void disconnect_whenUnBonded_removeStateMachine() {
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTING, STATE_DISCONNECTED);
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_CONNECTING);
+ generateConnectionMessageFromNative(mDevice, STATE_DISCONNECTING, STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
- // Send a message to trigger volume state changed broadcast
- generateVolumeStateChanged(mDevice, group_id, volume, flags, mute, isAutonomous);
+ doReturn(BOND_NONE).when(mAdapterService).getBondState(any());
+ mService.bondStateChanged(mDevice, BOND_NONE);
+ assertThat(mService.getDevices()).contains(mDevice);
+
+ generateConnectionMessageFromNative(mDevice, STATE_DISCONNECTED, STATE_DISCONNECTING);
+
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_DISCONNECTED);
+ assertThat(mService.getDevices()).doesNotContain(mDevice);
}
int getLeAudioVolume(int index, int minIndex, int maxIndex, int streamType) {
@@ -591,7 +425,7 @@ public class VolumeControlServiceTest {
}
@Test
- public void testAutonomousVolumeStateChange() {
+ public void incomingAutonomousVolumeStateChange_isApplied() {
// Make device Active now. This will trigger setting volume to AF
when(mLeAudioService.getActiveGroupId()).thenReturn(TEST_GROUP_ID);
@@ -602,9 +436,8 @@ public class VolumeControlServiceTest {
testVolumeCalculations(AudioManager.STREAM_MUSIC, MEDIA_MIN_VOL, MEDIA_MAX_VOL);
}
- /** Test if autonomous Mute/Unmute propagates the event to audio manager. */
@Test
- public void testAutonomousMuteUnmute() {
+ public void incomingAutonomousMuteUnmute_isApplied() {
int streamType = AudioManager.STREAM_MUSIC;
int streamVol = getLeAudioVolume(19, MEDIA_MIN_VOL, MEDIA_MAX_VOL, streamType);
@@ -626,43 +459,41 @@ public class VolumeControlServiceTest {
.adjustStreamVolume(eq(streamType), eq(AudioManager.ADJUST_UNMUTE), anyInt());
}
- /** Test Volume Control cache. */
@Test
- public void testVolumeCache() throws Exception {
+ public void volumeCache() {
int groupId = 1;
int volume = 6;
- Assert.assertEquals(-1, mService.getGroupVolume(groupId));
- mServiceBinder.setGroupVolume(groupId, volume, mAttributionSource);
+ assertThat(mService.getGroupVolume(groupId)).isEqualTo(-1);
+ mBinder.setGroupVolume(groupId, volume, mAttributionSource);
- int groupVolume = mServiceBinder.getGroupVolume(groupId, mAttributionSource);
- Assert.assertEquals(volume, groupVolume);
+ int groupVolume = mBinder.getGroupVolume(groupId, mAttributionSource);
+ assertThat(groupVolume).isEqualTo(volume);
volume = 10;
// Send autonomous volume change.
generateVolumeStateChanged(null, groupId, volume, 0, false, true);
- Assert.assertEquals(volume, mService.getGroupVolume(groupId));
+ assertThat(mService.getGroupVolume(groupId)).isEqualTo(volume);
}
- /** Test Active Group change */
@Test
- public void testActiveGroupChange() throws Exception {
+ public void activeGroupChange() {
int groupId_1 = 1;
int volume_groupId_1 = 6;
int groupId_2 = 2;
int volume_groupId_2 = 20;
- Assert.assertEquals(-1, mService.getGroupVolume(groupId_1));
- Assert.assertEquals(-1, mService.getGroupVolume(groupId_2));
- mServiceBinder.setGroupVolume(groupId_1, volume_groupId_1, mAttributionSource);
+ assertThat(mService.getGroupVolume(groupId_1)).isEqualTo(-1);
+ assertThat(mService.getGroupVolume(groupId_2)).isEqualTo(-1);
+ mBinder.setGroupVolume(groupId_1, volume_groupId_1, mAttributionSource);
- mServiceBinder.setGroupVolume(groupId_2, volume_groupId_2, mAttributionSource);
+ mBinder.setGroupVolume(groupId_2, volume_groupId_2, mAttributionSource);
// Make device Active now. This will trigger setting volume to AF
when(mLeAudioService.getActiveGroupId()).thenReturn(groupId_1);
- mServiceBinder.setGroupActive(groupId_1, true, mAttributionSource);
+ mBinder.setGroupActive(groupId_1, true, mAttributionSource);
// Expected index for STREAM_MUSIC
int expectedVol =
@@ -671,77 +502,76 @@ public class VolumeControlServiceTest {
// Make device Active now. This will trigger setting volume to AF
when(mLeAudioService.getActiveGroupId()).thenReturn(groupId_2);
- mServiceBinder.setGroupActive(groupId_2, true, mAttributionSource);
+ mBinder.setGroupActive(groupId_2, true, mAttributionSource);
expectedVol =
(int) Math.round((double) (volume_groupId_2 * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL);
verify(mAudioManager).setStreamVolume(anyInt(), eq(expectedVol), anyInt());
}
- /** Test Volume Control Mute cache. */
@Test
- public void testMuteCache() throws Exception {
+ public void muteCache() {
int groupId = 1;
int volume = 6;
- Assert.assertEquals(false, mService.getGroupMute(groupId));
+ assertThat(mService.getGroupMute(groupId)).isFalse();
// Send autonomous volume change
generateVolumeStateChanged(null, groupId, volume, 0, false, true);
// Mute
- mServiceBinder.muteGroup(groupId, mAttributionSource);
- Assert.assertEquals(true, mService.getGroupMute(groupId));
+ mBinder.muteGroup(groupId, mAttributionSource);
+ assertThat(mService.getGroupMute(groupId)).isTrue();
// Make sure the volume is kept even when muted
- Assert.assertEquals(volume, mService.getGroupVolume(groupId));
+ assertThat(mService.getGroupVolume(groupId)).isEqualTo(volume);
// Send autonomous unmute
generateVolumeStateChanged(null, groupId, volume, 0, false, true);
- Assert.assertEquals(false, mService.getGroupMute(groupId));
+ assertThat(mService.getGroupMute(groupId)).isFalse();
}
/** Test Volume Control with muted stream. */
@Test
- public void testVolumeChangeWhileMuted() throws Exception {
+ public void volumeChangeWhileMuted() {
int groupId = 1;
int volume = 6;
- Assert.assertEquals(false, mService.getGroupMute(groupId));
+ assertThat(mService.getGroupMute(groupId)).isFalse();
generateVolumeStateChanged(null, groupId, volume, 0, false, true);
// Mute
mService.muteGroup(groupId);
- Assert.assertEquals(true, mService.getGroupMute(groupId));
+ assertThat(mService.getGroupMute(groupId)).isTrue();
verify(mNativeInterface).muteGroup(eq(groupId));
// Make sure the volume is kept even when muted
doReturn(true).when(mAudioManager).isStreamMute(eq(AudioManager.STREAM_MUSIC));
- Assert.assertEquals(volume, mService.getGroupVolume(groupId));
+ assertThat(mService.getGroupVolume(groupId)).isEqualTo(volume);
// Lower the volume and keep it mute
mService.setGroupVolume(groupId, --volume);
- Assert.assertEquals(true, mService.getGroupMute(groupId));
+ assertThat(mService.getGroupMute(groupId)).isTrue();
verify(mNativeInterface).setGroupVolume(eq(groupId), eq(volume));
- verify(mNativeInterface, times(0)).unmuteGroup(eq(groupId));
+ verify(mNativeInterface, never()).unmuteGroup(eq(groupId));
// Don't unmute on consecutive calls either
mService.setGroupVolume(groupId, --volume);
- Assert.assertEquals(true, mService.getGroupMute(groupId));
+ assertThat(mService.getGroupMute(groupId)).isTrue();
verify(mNativeInterface).setGroupVolume(eq(groupId), eq(volume));
- verify(mNativeInterface, times(0)).unmuteGroup(eq(groupId));
+ verify(mNativeInterface, never()).unmuteGroup(eq(groupId));
// Raise the volume and unmute
volume += 10; // avoid previous volume levels and simplify mock verification
doReturn(false).when(mAudioManager).isStreamMute(eq(AudioManager.STREAM_MUSIC));
mService.setGroupVolume(groupId, ++volume);
- Assert.assertEquals(false, mService.getGroupMute(groupId));
+ assertThat(mService.getGroupMute(groupId)).isFalse();
verify(mNativeInterface).setGroupVolume(eq(groupId), eq(volume));
// Verify the number of unmute calls after the second volume change
mService.setGroupVolume(groupId, ++volume);
- Assert.assertEquals(false, mService.getGroupMute(groupId));
+ assertThat(mService.getGroupMute(groupId)).isFalse();
verify(mNativeInterface).setGroupVolume(eq(groupId), eq(volume));
// Make sure we unmuted only once
verify(mNativeInterface).unmuteGroup(eq(groupId));
@@ -750,7 +580,7 @@ public class VolumeControlServiceTest {
/** Test if phone will set volume which is read from the buds */
@Test
@EnableFlags(Flags.FLAG_LEAUDIO_BROADCAST_VOLUME_CONTROL_PRIMARY_GROUP_ONLY)
- public void testConnectedDeviceWithUserPersistFlagSet() throws Exception {
+ public void connectedDeviceWithUserPersistFlagSet() {
int groupId = 1;
int volumeDevice = 56;
int volumeDeviceTwo = 100;
@@ -762,29 +592,20 @@ public class VolumeControlServiceTest {
when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId);
when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(groupId);
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(
- any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
generateDeviceAvailableMessageFromNative(mDevice, 1);
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
when(mBassClientService.getSyncedBroadcastSinks()).thenReturn(new ArrayList<>());
// Group is not active unicast and not active primary broadcast, AF will not be notified
generateVolumeStateChanged(
mDevice, groupId, volumeDevice, flags, initialMuteState, initialAutonomousFlag);
- verify(mAudioManager, times(0)).setStreamVolume(anyInt(), anyInt(), anyInt());
+ verify(mAudioManager, never()).setStreamVolume(anyInt(), anyInt(), anyInt());
// Make device Active now. This will trigger setting volume to AF
when(mLeAudioService.getActiveGroupId()).thenReturn(groupId);
- mServiceBinder.setGroupActive(groupId, true, mAttributionSource);
+ mBinder.setGroupActive(groupId, true, mAttributionSource);
int expectedAfVol =
(int) Math.round((double) (volumeDevice * MEDIA_MAX_VOL) / BT_LE_AUDIO_MAX_VOL);
verify(mAudioManager).setStreamVolume(anyInt(), eq(expectedAfVol), anyInt());
@@ -792,11 +613,9 @@ public class VolumeControlServiceTest {
// Connect second device and read different volume. Expect it will be set to AF and to
// another set member
generateDeviceAvailableMessageFromNative(mDeviceTwo, 1);
- generateConnectionMessageFromNative(
- mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
- Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
+ generateConnectionMessageFromNative(mDeviceTwo, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDeviceTwo)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDeviceTwo);
// Group is now active, AF will be notified. Native will take care to sync the volume
generateVolumeStateChanged(
@@ -828,19 +647,10 @@ public class VolumeControlServiceTest {
when(mAudioManager.getStreamVolume(anyInt())).thenReturn(streamVolume);
when(mAudioManager.getStreamMaxVolume(anyInt())).thenReturn(streamMaxVolume);
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(
- any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
generateDeviceAvailableMessageFromNative(mDevice, 1);
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
int expectedAfVol =
(int) Math.round((double) streamVolume * BT_LE_AUDIO_MAX_VOL / streamMaxVolume);
@@ -853,11 +663,11 @@ public class VolumeControlServiceTest {
resetFlag,
initialMuteState,
initialAutonomousFlag);
- verify(mAudioManager, times(0)).setStreamVolume(anyInt(), anyInt(), anyInt());
+ verify(mAudioManager, never()).setStreamVolume(anyInt(), anyInt(), anyInt());
// Make device Active now. This will trigger setting volume to AF
when(mLeAudioService.getActiveGroupId()).thenReturn(groupId);
- mServiceBinder.setGroupActive(groupId, true, mAttributionSource);
+ mBinder.setGroupActive(groupId, true, mAttributionSource);
verify(mAudioManager).setStreamVolume(anyInt(), eq(streamVolume), anyInt());
verify(mNativeInterface).setGroupVolume(eq(groupId), eq(expectedAfVol));
@@ -865,11 +675,9 @@ public class VolumeControlServiceTest {
// Connect second device and read different volume. Expect it will be set to AF and to
// another set member
generateDeviceAvailableMessageFromNative(mDeviceTwo, 1);
- generateConnectionMessageFromNative(
- mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
- Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
+ generateConnectionMessageFromNative(mDeviceTwo, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDeviceTwo)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDeviceTwo);
// Group is now active, AF will be notified. Native will take care to sync the volume
generateVolumeStateChanged(
@@ -886,13 +694,13 @@ public class VolumeControlServiceTest {
/** Test if phone will set volume which is read from the buds */
@Test
- public void testConnectedDeviceWithResetFlagSetWithNonZeroVolume() throws Exception {
+ public void connectedDeviceWithResetFlagSetWithNonZeroVolume() {
testConnectedDeviceWithResetFlag(56, 100);
}
/** Test if phone will set volume to buds which has no volume */
@Test
- public void testConnectedDeviceWithResetFlagSetWithZeroVolume() throws Exception {
+ public void connectedDeviceWithResetFlagSetWithZeroVolume() {
testConnectedDeviceWithResetFlag(0, 0);
}
@@ -901,7 +709,7 @@ public class VolumeControlServiceTest {
* already changed and cached.
*/
@Test
- public void testLateConnectingDevice() throws Exception {
+ public void lateConnectingDevice() {
int groupId = 1;
int groupVolume = 56;
@@ -909,29 +717,18 @@ public class VolumeControlServiceTest {
when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId);
when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(groupId);
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(
- any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
mService.setGroupVolume(groupId, groupVolume);
verify(mNativeInterface).setGroupVolume(eq(groupId), eq(groupVolume));
- verify(mNativeInterface, times(0)).setVolume(eq(mDeviceTwo), eq(groupVolume));
+ verify(mNativeInterface, never()).setVolume(eq(mDeviceTwo), eq(groupVolume));
// Verify that second device gets the proper group volume level when connected
- generateConnectionMessageFromNative(
- mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
- Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
+ generateConnectionMessageFromNative(mDeviceTwo, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDeviceTwo)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDeviceTwo);
verify(mNativeInterface).setVolume(eq(mDeviceTwo), eq(groupVolume));
}
@@ -940,7 +737,7 @@ public class VolumeControlServiceTest {
* group was already changed and cached.
*/
@Test
- public void testLateDiscoveredGroupMember() throws Exception {
+ public void lateDiscoveredGroupMember() {
int groupId = 1;
int groupVolume = 56;
@@ -948,29 +745,18 @@ public class VolumeControlServiceTest {
when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId);
when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(-1);
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(
- any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
// Set the group volume
mService.setGroupVolume(groupId, groupVolume);
// Verify that second device will not get the group volume level if it is not a group member
- generateConnectionMessageFromNative(
- mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
- Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
- verify(mNativeInterface, times(0)).setVolume(eq(mDeviceTwo), eq(groupVolume));
+ generateConnectionMessageFromNative(mDeviceTwo, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDeviceTwo)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDeviceTwo);
+ verify(mNativeInterface, never()).setVolume(eq(mDeviceTwo), eq(groupVolume));
// But gets the volume when it becomes the group member
when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(groupId);
@@ -984,7 +770,7 @@ public class VolumeControlServiceTest {
* telephony, thus setting volume level to 0 is considered as muting.
*/
@Test
- public void testMuteLateConnectingDevice() throws Exception {
+ public void muteLateConnectingDevice() {
int groupId = 1;
int volume = 100;
@@ -992,36 +778,25 @@ public class VolumeControlServiceTest {
when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId);
when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(groupId);
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(
- any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
// Set the initial volume and mute conditions
doReturn(true).when(mAudioManager).isStreamMute(anyInt());
mService.setGroupVolume(groupId, volume);
verify(mNativeInterface).setGroupVolume(eq(groupId), eq(volume));
- verify(mNativeInterface, times(0)).setVolume(eq(mDeviceTwo), eq(volume));
+ verify(mNativeInterface, never()).setVolume(eq(mDeviceTwo), eq(volume));
// Check if it was muted
verify(mNativeInterface).muteGroup(eq(groupId));
- Assert.assertEquals(true, mService.getGroupMute(groupId));
+ assertThat(mService.getGroupMute(groupId)).isTrue();
// Verify that second device gets the proper group volume level when connected
- generateConnectionMessageFromNative(
- mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
- Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
+ generateConnectionMessageFromNative(mDeviceTwo, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDeviceTwo)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDeviceTwo);
verify(mNativeInterface).setVolume(eq(mDeviceTwo), eq(volume));
// Check if new device was muted
verify(mNativeInterface).mute(eq(mDeviceTwo));
@@ -1033,7 +808,7 @@ public class VolumeControlServiceTest {
* than telephony, thus setting volume level to 0 is considered as muting.
*/
@Test
- public void testMuteLateDiscoveredGroupMember() throws Exception {
+ public void muteLateDiscoveredGroupMember() {
int groupId = 1;
int volume = 100;
@@ -1041,32 +816,21 @@ public class VolumeControlServiceTest {
when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId);
when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(-1);
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(
- any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
// Set the initial volume and mute conditions
doReturn(true).when(mAudioManager).isStreamMute(anyInt());
mService.setGroupVolume(groupId, volume);
// Verify that second device will not get the group volume level if it is not a group member
- generateConnectionMessageFromNative(
- mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
- Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
- verify(mNativeInterface, times(0)).setVolume(eq(mDeviceTwo), eq(volume));
+ generateConnectionMessageFromNative(mDeviceTwo, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDeviceTwo)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDeviceTwo);
+ verify(mNativeInterface, never()).setVolume(eq(mDeviceTwo), eq(volume));
// Check if it was not muted
- verify(mNativeInterface, times(0)).mute(eq(mDeviceTwo));
+ verify(mNativeInterface, never()).mute(eq(mDeviceTwo));
// But gets the volume when it becomes the group member
when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(groupId);
@@ -1076,43 +840,40 @@ public class VolumeControlServiceTest {
}
@Test
- public void testServiceBinderGetDevicesMatchingConnectionStates() throws Exception {
- List<BluetoothDevice> devices =
- mServiceBinder.getDevicesMatchingConnectionStates(null, mAttributionSource);
- Assert.assertEquals(0, devices.size());
+ public void serviceBinderGetDevicesMatchingConnectionStates() {
+ assertThat(mBinder.getDevicesMatchingConnectionStates(null, mAttributionSource)).isEmpty();
}
@Test
- public void testServiceBinderSetConnectionPolicy() throws Exception {
- Assert.assertTrue(
- mServiceBinder.setConnectionPolicy(
- mDevice, BluetoothProfile.CONNECTION_POLICY_UNKNOWN, mAttributionSource));
+ public void serviceBinderSetConnectionPolicy() {
+ assertThat(
+ mBinder.setConnectionPolicy(
+ mDevice, CONNECTION_POLICY_UNKNOWN, mAttributionSource))
+ .isTrue();
verify(mDatabaseManager)
.setProfileConnectionPolicy(
- mDevice,
- BluetoothProfile.VOLUME_CONTROL,
- BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
+ mDevice, BluetoothProfile.VOLUME_CONTROL, CONNECTION_POLICY_UNKNOWN);
}
@Test
- public void testServiceBinderVolumeOffsetMethods() throws Exception {
+ public void serviceBinderVolumeOffsetMethods() {
// Send a message to trigger connection completed
generateDeviceAvailableMessageFromNative(mDevice, 2);
- Assert.assertTrue(mServiceBinder.isVolumeOffsetAvailable(mDevice, mAttributionSource));
+ assertThat(mBinder.isVolumeOffsetAvailable(mDevice, mAttributionSource)).isTrue();
int numberOfInstances =
- mServiceBinder.getNumberOfVolumeOffsetInstances(mDevice, mAttributionSource);
- Assert.assertEquals(2, numberOfInstances);
+ mBinder.getNumberOfVolumeOffsetInstances(mDevice, mAttributionSource);
+ assertThat(numberOfInstances).isEqualTo(2);
int id = 1;
int volumeOffset = 100;
- mServiceBinder.setVolumeOffset(mDevice, id, volumeOffset, mAttributionSource);
+ mBinder.setVolumeOffset(mDevice, id, volumeOffset, mAttributionSource);
verify(mNativeInterface).setExtAudioOutVolumeOffset(mDevice, id, volumeOffset);
}
@Test
- public void testServiceBinderSetDeviceVolumeMethods() throws Exception {
+ public void serviceBinderSetDeviceVolumeMethods() {
int groupId = 1;
int groupVolume = 56;
int deviceOneVolume = 46;
@@ -1122,36 +883,43 @@ public class VolumeControlServiceTest {
when(mLeAudioService.getGroupId(mDevice)).thenReturn(groupId);
when(mLeAudioService.getGroupId(mDeviceTwo)).thenReturn(groupId);
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(
- any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
generateDeviceAvailableMessageFromNative(mDevice, 1);
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
- mServiceBinder.setDeviceVolume(mDevice, groupVolume, true, mAttributionSource);
+ mBinder.setDeviceVolume(mDevice, groupVolume, true, mAttributionSource);
verify(mNativeInterface).setGroupVolume(groupId, groupVolume);
- Assert.assertEquals(groupVolume, mService.getGroupVolume(groupId));
+ assertThat(mService.getGroupVolume(groupId)).isEqualTo(groupVolume);
- mServiceBinder.setDeviceVolume(mDevice, deviceOneVolume, false, mAttributionSource);
+ mBinder.setDeviceVolume(mDevice, deviceOneVolume, false, mAttributionSource);
verify(mNativeInterface).setVolume(mDevice, deviceOneVolume);
- Assert.assertEquals(deviceOneVolume, mService.getDeviceVolume(mDevice));
+ assertThat(mService.getDeviceVolume(mDevice)).isEqualTo(deviceOneVolume);
Assert.assertNotEquals(deviceOneVolume, mService.getDeviceVolume(mDeviceTwo));
- mServiceBinder.setDeviceVolume(mDeviceTwo, deviceTwoVolume, false, mAttributionSource);
+ mBinder.setDeviceVolume(mDeviceTwo, deviceTwoVolume, false, mAttributionSource);
verify(mNativeInterface).setVolume(mDeviceTwo, deviceTwoVolume);
- Assert.assertEquals(deviceTwoVolume, mService.getDeviceVolume(mDeviceTwo));
+ assertThat(mService.getDeviceVolume(mDeviceTwo)).isEqualTo(deviceTwoVolume);
Assert.assertNotEquals(deviceTwoVolume, mService.getDeviceVolume(mDevice));
}
@Test
+ @EnableFlags(Flags.FLAG_LEAUDIO_BROADCAST_VOLUME_CONTROL_FOR_CONNECTED_DEVICES)
+ public void testServiceBinderSetDeviceVolumeNoGroupId() throws Exception {
+ int deviceVolume = 42;
+ when(mLeAudioService.getGroupId(mDevice)).thenReturn(LE_AUDIO_GROUP_ID_INVALID);
+
+ generateDeviceAvailableMessageFromNative(mDevice, 1);
+ generateConnectionMessageFromNative(
+ mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
+
+ mBinder.setDeviceVolume(mDevice, deviceVolume, false, mAttributionSource);
+ verify(mNativeInterface).setVolume(mDevice, deviceVolume);
+ assertThat(mService.getDeviceVolume(mDevice)).isEqualTo(deviceVolume);
+ }
+
+ @Test
public void testServiceBinderRegisterUnregisterCallback() throws Exception {
IBluetoothVolumeControlCallback callback =
Mockito.mock(IBluetoothVolumeControlCallback.class);
@@ -1161,15 +929,15 @@ public class VolumeControlServiceTest {
synchronized (mService.mCallbacks) {
int size = mService.mCallbacks.getRegisteredCallbackCount();
mService.registerCallback(callback);
- Assert.assertEquals(size + 1, mService.mCallbacks.getRegisteredCallbackCount());
+ assertThat(mService.mCallbacks.getRegisteredCallbackCount()).isEqualTo(size + 1);
mService.unregisterCallback(callback);
- Assert.assertEquals(size, mService.mCallbacks.getRegisteredCallbackCount());
+ assertThat(mService.mCallbacks.getRegisteredCallbackCount()).isEqualTo(size);
}
}
@Test
- public void testServiceBinderRegisterCallbackWhenDeviceAlreadyConnected() throws Exception {
+ public void serviceBinderRegisterCallbackWhenDeviceAlreadyConnected() throws Exception {
int groupId = 1;
int groupVolume = 56;
@@ -1177,31 +945,20 @@ public class VolumeControlServiceTest {
when(mCsipService.getGroupId(mDevice, BluetoothUuid.CAP)).thenReturn(groupId);
when(mCsipService.getGroupId(mDeviceTwo, BluetoothUuid.CAP)).thenReturn(groupId);
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(
- any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
generateDeviceAvailableMessageFromNative(mDevice, 2);
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
mService.setGroupVolume(groupId, groupVolume);
verify(mNativeInterface).setGroupVolume(eq(groupId), eq(groupVolume));
- verify(mNativeInterface, times(0)).setVolume(eq(mDeviceTwo), eq(groupVolume));
+ verify(mNativeInterface, never()).setVolume(eq(mDeviceTwo), eq(groupVolume));
// Verify that second device gets the proper group volume level when connected
generateDeviceAvailableMessageFromNative(mDeviceTwo, 1);
- generateConnectionMessageFromNative(
- mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
- Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
+ generateConnectionMessageFromNative(mDeviceTwo, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDeviceTwo)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDeviceTwo);
verify(mNativeInterface).setVolume(eq(mDeviceTwo), eq(groupVolume));
// Generate events for both devices
@@ -1229,7 +986,7 @@ public class VolumeControlServiceTest {
synchronized (mService.mCallbacks) {
int size = mService.mCallbacks.getRegisteredCallbackCount();
mService.registerCallback(callback);
- Assert.assertEquals(size + 1, mService.mCallbacks.getRegisteredCallbackCount());
+ assertThat(mService.mCallbacks.getRegisteredCallbackCount()).isEqualTo(size + 1);
}
verify(callback).onVolumeOffsetChanged(eq(mDevice), eq(1), eq(100));
@@ -1259,35 +1016,25 @@ public class VolumeControlServiceTest {
}
@Test
- public void testServiceBinderRegisterVolumeChangedCallbackWhenDeviceAlreadyConnected()
+ @EnableFlags(Flags.FLAG_LEAUDIO_BROADCAST_VOLUME_CONTROL_FOR_CONNECTED_DEVICES)
+ public void serviceBinderRegisterVolumeChangedCallbackWhenDeviceAlreadyConnected()
throws Exception {
int groupId = 1;
int deviceOneVolume = 46;
int deviceTwoVolume = 36;
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(
- any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
generateDeviceAvailableMessageFromNative(mDevice, 1);
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
mService.setDeviceVolume(mDevice, deviceOneVolume, false);
verify(mNativeInterface).setVolume(eq(mDevice), eq(deviceOneVolume));
// Verify that second device gets the proper group volume level when connected
generateDeviceAvailableMessageFromNative(mDeviceTwo, 1);
- generateConnectionMessageFromNative(
- mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
- Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
+ generateConnectionMessageFromNative(mDeviceTwo, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDeviceTwo)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDeviceTwo);
mService.setDeviceVolume(mDeviceTwo, deviceTwoVolume, false);
verify(mNativeInterface).setVolume(eq(mDeviceTwo), eq(deviceTwoVolume));
@@ -1304,7 +1051,7 @@ public class VolumeControlServiceTest {
synchronized (mService.mCallbacks) {
int size = mService.mCallbacks.getRegisteredCallbackCount();
mService.registerCallback(callback);
- Assert.assertEquals(size + 1, mService.mCallbacks.getRegisteredCallbackCount());
+ assertThat(mService.mCallbacks.getRegisteredCallbackCount()).isEqualTo(size + 1);
}
verify(callback).onDeviceVolumeChanged(eq(mDevice), eq(deviceOneVolume));
@@ -1312,34 +1059,23 @@ public class VolumeControlServiceTest {
}
@Test
- public void testServiceBinderTestNotifyNewRegisteredCallback() throws Exception {
+ public void serviceBinderTestNotifyNewRegisteredCallback() throws Exception {
int groupId = 1;
int deviceOneVolume = 46;
int deviceTwoVolume = 36;
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(
- any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
generateDeviceAvailableMessageFromNative(mDevice, 1);
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
mService.setDeviceVolume(mDevice, deviceOneVolume, false);
verify(mNativeInterface).setVolume(eq(mDevice), eq(deviceOneVolume));
// Verify that second device gets the proper group volume level when connected
generateDeviceAvailableMessageFromNative(mDeviceTwo, 1);
- generateConnectionMessageFromNative(
- mDeviceTwo, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDeviceTwo));
- Assert.assertTrue(mService.getDevices().contains(mDeviceTwo));
+ generateConnectionMessageFromNative(mDeviceTwo, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDeviceTwo)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDeviceTwo);
mService.setDeviceVolume(mDeviceTwo, deviceTwoVolume, false);
verify(mNativeInterface).setVolume(eq(mDeviceTwo), eq(deviceTwoVolume));
@@ -1357,7 +1093,7 @@ public class VolumeControlServiceTest {
synchronized (mService.mCallbacks) {
size = mService.mCallbacks.getRegisteredCallbackCount();
mService.registerCallback(callback);
- Assert.assertEquals(size + 1, mService.mCallbacks.getRegisteredCallbackCount());
+ assertThat(mService.mCallbacks.getRegisteredCallbackCount()).isEqualTo(size + 1);
}
IBluetoothVolumeControlCallback callback_new_client =
@@ -1365,47 +1101,47 @@ public class VolumeControlServiceTest {
Binder binder_new_client = Mockito.mock(Binder.class);
when(callback_new_client.asBinder()).thenReturn(binder_new_client);
- mServiceBinder.notifyNewRegisteredCallback(callback_new_client, mAttributionSource);
+ mLooper.startAutoDispatch();
+ mBinder.notifyNewRegisteredCallback(callback_new_client, mAttributionSource);
+ mLooper.stopAutoDispatch();
+
synchronized (mService.mCallbacks) {
- Assert.assertEquals(size + 1, mService.mCallbacks.getRegisteredCallbackCount());
+ assertThat(mService.mCallbacks.getRegisteredCallbackCount()).isEqualTo(size + 1);
}
// This shall be done only once after mService.registerCallback
verify(callback).onDeviceVolumeChanged(eq(mDevice), eq(deviceOneVolume));
verify(callback).onDeviceVolumeChanged(eq(mDeviceTwo), eq(deviceTwoVolume));
- // This shall be done only once after mServiceBinder.updateNewRegisteredCallback
+ // This shall be done only once after mBinder.updateNewRegisteredCallback
verify(callback_new_client).onDeviceVolumeChanged(eq(mDevice), eq(deviceOneVolume));
verify(callback_new_client).onDeviceVolumeChanged(eq(mDeviceTwo), eq(deviceTwoVolume));
}
@Test
- public void testServiceBinderMuteMethods() throws Exception {
- mServiceBinder.mute(mDevice, mAttributionSource);
+ public void serviceBinderMuteMethods() {
+ mBinder.mute(mDevice, mAttributionSource);
verify(mNativeInterface).mute(mDevice);
- mServiceBinder.unmute(mDevice, mAttributionSource);
+ mBinder.unmute(mDevice, mAttributionSource);
verify(mNativeInterface).unmute(mDevice);
int groupId = 1;
- mServiceBinder.muteGroup(groupId, mAttributionSource);
+ mBinder.muteGroup(groupId, mAttributionSource);
verify(mNativeInterface).muteGroup(groupId);
- mServiceBinder.unmuteGroup(groupId, mAttributionSource);
+ mBinder.unmuteGroup(groupId, mAttributionSource);
verify(mNativeInterface).unmuteGroup(groupId);
}
@Test
- public void testDump_doesNotCrash() throws Exception {
- connectDevice(mDevice);
-
+ public void dump_doesNotCrash() {
StringBuilder sb = new StringBuilder();
mService.dump(sb);
}
- /** Test Volume Control changed callback. */
@Test
- public void testVolumeControlChangedCallback() throws Exception {
+ public void volumeControlChangedCallback() throws Exception {
int groupId = 1;
int groupVolume = 56;
int deviceOneVolume = 46;
@@ -1417,7 +1153,7 @@ public class VolumeControlServiceTest {
// Send a message to trigger connection completed
generateDeviceAvailableMessageFromNative(mDevice, 2);
- mServiceBinder.setDeviceVolume(mDevice, groupVolume, true, mAttributionSource);
+ mBinder.setDeviceVolume(mDevice, groupVolume, true, mAttributionSource);
verify(mNativeInterface).setGroupVolume(eq(groupId), eq(groupVolume));
// Register callback and verify it is called with known devices
@@ -1429,7 +1165,7 @@ public class VolumeControlServiceTest {
synchronized (mService.mCallbacks) {
int size = mService.mCallbacks.getRegisteredCallbackCount();
mService.registerCallback(callback);
- Assert.assertEquals(size + 1, mService.mCallbacks.getRegisteredCallbackCount());
+ assertThat(mService.mCallbacks.getRegisteredCallbackCount()).isEqualTo(size + 1);
}
when(mLeAudioService.getGroupDevices(groupId))
@@ -1451,7 +1187,7 @@ public class VolumeControlServiceTest {
/** Test Volume Control changed for broadcast primary group. */
@Test
@EnableFlags(Flags.FLAG_LEAUDIO_BROADCAST_VOLUME_CONTROL_PRIMARY_GROUP_ONLY)
- public void testVolumeControlChangedForBroadcastPrimaryGroup() throws Exception {
+ public void volumeControlChangedForBroadcastPrimaryGroup() {
int groupId = 1;
int groupVolume = 30;
@@ -1461,19 +1197,10 @@ public class VolumeControlServiceTest {
when(mAudioManager.getStreamVolume(anyInt())).thenReturn(groupVolume);
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(
- any(BluetoothDevice.class), eq(BluetoothProfile.VOLUME_CONTROL)))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(any(BluetoothDevice.class));
-
generateDeviceAvailableMessageFromNative(mDevice, 1);
- generateConnectionMessageFromNative(
- mDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(mDevice));
- Assert.assertTrue(mService.getDevices().contains(mDevice));
+ generateConnectionMessageFromNative(mDevice, STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mService.getConnectionState(mDevice)).isEqualTo(STATE_CONNECTED);
+ assertThat(mService.getDevices()).contains(mDevice);
// Make active group as null and broadcast active
when(mLeAudioService.getActiveGroupId()).thenReturn(LE_AUDIO_GROUP_ID_INVALID);
@@ -1481,7 +1208,7 @@ public class VolumeControlServiceTest {
// Group is broadcast primary group, AF will not be notified
generateVolumeStateChanged(null, groupId, groupVolume, 0, false, true);
- verify(mAudioManager, times(0)).setStreamVolume(anyInt(), anyInt(), anyInt());
+ verify(mAudioManager, never()).setStreamVolume(anyInt(), anyInt(), anyInt());
// Make active group as null and broadcast active
when(mLeAudioService.getActiveGroupId()).thenReturn(LE_AUDIO_GROUP_ID_INVALID);
@@ -1496,55 +1223,6 @@ public class VolumeControlServiceTest {
verify(mAudioManager).setStreamVolume(anyInt(), anyInt(), anyInt());
}
- private void connectDevice(BluetoothDevice device) throws Exception {
- VolumeControlStackEvent connCompletedEvent;
-
- List<BluetoothDevice> prevConnectedDevices = mService.getConnectedDevices();
-
- // Update the device policy so okToConnect() returns true
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.VOLUME_CONTROL))
- .thenReturn(BluetoothProfile.CONNECTION_POLICY_ALLOWED);
- doReturn(true).when(mNativeInterface).connectVolumeControl(device);
- doReturn(true).when(mNativeInterface).disconnectVolumeControl(device);
-
- // Send a connect request
- Assert.assertTrue("Connect failed", mService.connect(device));
-
- // Verify the connection state broadcast, and that we are in Connecting state
- verifyConnectionStateIntent(
- TIMEOUT_MS,
- device,
- BluetoothProfile.STATE_CONNECTING,
- BluetoothProfile.STATE_DISCONNECTED);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTING, mService.getConnectionState(device));
-
- // Send a message to trigger connection completed
- connCompletedEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- connCompletedEvent.device = device;
- connCompletedEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTED;
- mService.messageFromNative(connCompletedEvent);
-
- // Verify the connection state broadcast, and that we are in Connected state
- verifyConnectionStateIntent(
- TIMEOUT_MS,
- device,
- BluetoothProfile.STATE_CONNECTED,
- BluetoothProfile.STATE_CONNECTING);
- Assert.assertEquals(BluetoothProfile.STATE_CONNECTED, mService.getConnectionState(device));
-
- // Verify that the device is in the list of connected devices
- List<BluetoothDevice> connectedDevices =
- mServiceBinder.getConnectedDevices(mAttributionSource);
- Assert.assertTrue(connectedDevices.contains(device));
- // Verify the list of previously connected devices
- for (BluetoothDevice prevDevice : prevConnectedDevices) {
- Assert.assertTrue(connectedDevices.contains(prevDevice));
- }
- }
-
private void generateConnectionMessageFromNative(
BluetoothDevice device, int newConnectionState, int oldConnectionState) {
VolumeControlStackEvent stackEvent =
@@ -1553,8 +1231,9 @@ public class VolumeControlServiceTest {
stackEvent.device = device;
stackEvent.valueInt1 = newConnectionState;
mService.messageFromNative(stackEvent);
- // Verify the connection state broadcast
- verifyConnectionStateIntent(TIMEOUT_MS, device, newConnectionState, oldConnectionState);
+ mLooper.dispatchAll();
+
+ verifyConnectionStateIntent(device, newConnectionState, oldConnectionState);
}
private void generateUnexpectedConnectionMessageFromNative(
@@ -1565,8 +1244,9 @@ public class VolumeControlServiceTest {
stackEvent.device = device;
stackEvent.valueInt1 = newConnectionState;
mService.messageFromNative(stackEvent);
- // Verify the connection state broadcast
- verifyNoConnectionStateIntent(TIMEOUT_MS, device);
+ mLooper.dispatchAll();
+
+ mInOrder.verify(mAdapterService, never()).sendBroadcast(any(), any());
}
private void generateDeviceAvailableMessageFromNative(
@@ -1634,20 +1314,18 @@ public class VolumeControlServiceTest {
mService.messageFromNative(event);
}
- /**
- * Helper function to test okToConnect() method
- *
- * @param device test device
- * @param bondState bond state value, could be invalid
- * @param policy value, could be invalid
- * @param expected expected result from okToConnect()
- */
- private void testOkToConnectCase(
- BluetoothDevice device, int bondState, int policy, boolean expected) {
- doReturn(bondState).when(mAdapterService).getBondState(device);
- when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
- when(mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.VOLUME_CONTROL))
- .thenReturn(policy);
- Assert.assertEquals(expected, mService.okToConnect(device));
+ @SafeVarargs
+ private void verifyIntentSent(Matcher<Intent>... matchers) {
+ mInOrder.verify(mAdapterService)
+ .sendBroadcast(MockitoHamcrest.argThat(AllOf.allOf(matchers)), any());
+ }
+
+ private void verifyConnectionStateIntent(BluetoothDevice device, int newState, int prevState) {
+ verifyIntentSent(
+ hasAction(BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED),
+ hasExtra(BluetoothDevice.EXTRA_DEVICE, device),
+ hasExtra(BluetoothProfile.EXTRA_STATE, newState),
+ hasExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState));
+ assertThat(mService.getConnectionState(device)).isEqualTo(newState);
}
}
diff --git a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java
index 11c59e1425..c7cca51983 100644
--- a/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java
+++ b/android/app/tests/unit/src/com/android/bluetooth/vc/VolumeControlStateMachineTest.java
@@ -17,412 +17,238 @@
package com.android.bluetooth.vc;
-import static org.mockito.Mockito.after;
+import static android.bluetooth.BluetoothProfile.EXTRA_PREVIOUS_STATE;
+import static android.bluetooth.BluetoothProfile.EXTRA_STATE;
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTED;
+import static android.bluetooth.BluetoothProfile.STATE_CONNECTING;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTED;
+import static android.bluetooth.BluetoothProfile.STATE_DISCONNECTING;
+import static android.bluetooth.BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED;
+
+import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction;
+import static androidx.test.espresso.intent.matcher.IntentMatchers.hasExtra;
+
+import static com.android.bluetooth.vc.VolumeControlStateMachine.MESSAGE_CONNECT;
+import static com.android.bluetooth.vc.VolumeControlStateMachine.MESSAGE_CONNECT_TIMEOUT;
+import static com.android.bluetooth.vc.VolumeControlStateMachine.MESSAGE_DISCONNECT;
+import static com.android.bluetooth.vc.VolumeControlStateMachine.MESSAGE_STACK_EVENT;
+
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.any;
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.inOrder;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
import android.content.Intent;
-import android.os.HandlerThread;
-import android.os.Message;
+import android.os.test.TestLooper;
import androidx.test.filters.MediumTest;
-import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.bluetooth.TestUtils;
-import com.android.bluetooth.btservice.AdapterService;
-import org.hamcrest.core.IsInstanceOf;
-import org.junit.After;
-import org.junit.Assert;
+import org.hamcrest.Matcher;
+import org.hamcrest.core.AllOf;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
import org.mockito.Mock;
-import org.mockito.Mockito;
+import org.mockito.hamcrest.MockitoHamcrest;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class VolumeControlStateMachineTest {
- private BluetoothAdapter mAdapter;
- private HandlerThread mHandlerThread = null;
- private VolumeControlStateMachine mVolumeControlStateMachine;
- private BluetoothDevice mTestDevice;
- private static final int TIMEOUT_MS = 1000;
-
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
- @Mock private AdapterService mAdapterService;
- @Mock private VolumeControlService mVolumeControlService;
- @Mock private VolumeControlNativeInterface mVolumeControlNativeInterface;
+ @Mock private VolumeControlService mService;
+ @Mock private VolumeControlNativeInterface mNativeInterface;
- boolean mIsAdapterServiceSet;
+ private final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
+ private final BluetoothDevice mDevice = TestUtils.getTestDevice(mAdapter, 39);
+
+ private VolumeControlStateMachine mStateMachine;
+ private InOrder mInOrder;
+ private TestLooper mLooper;
@Before
- public void setUp() throws Exception {
- InstrumentationRegistry.getInstrumentation()
- .getUiAutomation()
- .adoptShellPermissionIdentity();
- TestUtils.setAdapterService(mAdapterService);
-
- mAdapter = BluetoothAdapter.getDefaultAdapter();
- mIsAdapterServiceSet = true;
-
- // Get a device for testing
- mTestDevice = mAdapter.getRemoteDevice("00:01:02:03:04:05");
-
- // Set up thread and looper
- mHandlerThread = new HandlerThread("VolumeControlStateMachineTestHandlerThread");
- mHandlerThread.start();
- mVolumeControlStateMachine =
- new VolumeControlStateMachine(
- mTestDevice,
- mVolumeControlService,
- mVolumeControlNativeInterface,
- mHandlerThread.getLooper());
- // Override the timeout value to speed up the test
- mVolumeControlStateMachine.sConnectTimeoutMs = 1000; // 1s
- mVolumeControlStateMachine.start();
- }
+ public void setUp() {
+ doReturn(true).when(mService).okToConnect(any());
- @After
- public void tearDown() throws Exception {
- if (mHandlerThread != null) {
- mHandlerThread.quit();
- }
- if (mIsAdapterServiceSet) {
- TestUtils.clearAdapterService(mAdapterService);
- }
- }
+ doReturn(true).when(mNativeInterface).connectVolumeControl(any());
+ doReturn(true).when(mNativeInterface).disconnectVolumeControl(any());
- /** Test that default state is disconnected */
- @Test
- public void testDefaultDisconnectedState() {
- Assert.assertEquals(
- BluetoothProfile.STATE_DISCONNECTED,
- mVolumeControlStateMachine.getConnectionState());
+ mInOrder = inOrder(mService);
+ mLooper = new TestLooper();
+
+ mStateMachine =
+ new VolumeControlStateMachine(
+ mService, mDevice, mNativeInterface, mLooper.getLooper());
+ mStateMachine.start();
}
- /**
- * Allow/disallow connection to any device.
- *
- * @param allow if true, connection is allowed
- */
- private void allowConnection(boolean allow) {
- doReturn(allow).when(mVolumeControlService).okToConnect(any(BluetoothDevice.class));
+ @Test
+ public void initialState_isDisconnected() {
+ assertThat(mStateMachine.getConnectionState()).isEqualTo(STATE_DISCONNECTED);
}
- /** Test that an incoming connection with policy forbidding connection is rejected */
@Test
- public void testIncomingPolicyReject() {
- allowConnection(false);
+ public void incomingConnect_whenNotOkToConnect_isRejected() {
+ doReturn(false).when(mService).okToConnect(any());
// Inject an event for when incoming connection is requested
VolumeControlStackEvent connStCh =
new VolumeControlStackEvent(
VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- connStCh.device = mTestDevice;
- connStCh.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTED;
- mVolumeControlStateMachine.sendMessage(VolumeControlStateMachine.STACK_EVENT, connStCh);
-
- // Verify that no connection state broadcast is executed
- verify(mVolumeControlService, after(TIMEOUT_MS).never())
- .sendBroadcast(any(Intent.class), anyString());
- // Check that we are in Disconnected state
- Assert.assertThat(
- mVolumeControlStateMachine.getCurrentState(),
- IsInstanceOf.instanceOf(VolumeControlStateMachine.Disconnected.class));
+ connStCh.device = mDevice;
+ connStCh.valueInt1 = STATE_CONNECTED;
+ sendAndDispatchMessage(MESSAGE_STACK_EVENT, connStCh);
+
+ verify(mService, never()).sendBroadcast(any(Intent.class), anyString());
+ assertThat(mStateMachine.getCurrentState())
+ .isInstanceOf(VolumeControlStateMachine.Disconnected.class);
}
- /** Test that an incoming connection with policy allowing connection is accepted */
@Test
- public void testIncomingPolicyAccept() {
- allowConnection(true);
+ public void incomingConnect_whenOkToConnect_isConnected() {
+ generateConnectionMessageFromNative(STATE_CONNECTING, STATE_DISCONNECTED);
+ assertThat(mStateMachine.getCurrentState())
+ .isInstanceOf(VolumeControlStateMachine.Connecting.class);
+
+ generateConnectionMessageFromNative(STATE_CONNECTED, STATE_CONNECTING);
+ assertThat(mStateMachine.getCurrentState())
+ .isInstanceOf(VolumeControlStateMachine.Connected.class);
+ }
- // Inject an event for when incoming connection is requested
- VolumeControlStackEvent connStCh =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- connStCh.device = mTestDevice;
- connStCh.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTING;
- mVolumeControlStateMachine.sendMessage(VolumeControlStateMachine.STACK_EVENT, connStCh);
-
- // Verify that one connection state broadcast is executed
- ArgumentCaptor<Intent> intentArgument1 = ArgumentCaptor.forClass(Intent.class);
- verify(mVolumeControlService, timeout(TIMEOUT_MS).times(1))
- .sendBroadcast(intentArgument1.capture(), anyString());
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTING,
- intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
-
- // Check that we are in Connecting state
- Assert.assertThat(
- mVolumeControlStateMachine.getCurrentState(),
- IsInstanceOf.instanceOf(VolumeControlStateMachine.Connecting.class));
-
- // Send a message to trigger connection completed
- VolumeControlStackEvent connCompletedEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- connCompletedEvent.device = mTestDevice;
- connCompletedEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTED;
- mVolumeControlStateMachine.sendMessage(
- VolumeControlStateMachine.STACK_EVENT, connCompletedEvent);
-
- // Verify that the expected number of broadcasts are executed:
- // - two calls to broadcastConnectionState(): Disconnected -> Connecting -> Connected
- ArgumentCaptor<Intent> intentArgument2 = ArgumentCaptor.forClass(Intent.class);
- verify(mVolumeControlService, timeout(TIMEOUT_MS).times(2))
- .sendBroadcast(intentArgument2.capture(), anyString());
- // Check that we are in Connected state
- Assert.assertThat(
- mVolumeControlStateMachine.getCurrentState(),
- IsInstanceOf.instanceOf(VolumeControlStateMachine.Connected.class));
+ @Test
+ public void outgoingConnect_whenTimeOut_isDisconnectedAndInAcceptList() {
+ sendAndDispatchMessage(MESSAGE_CONNECT, mDevice);
+ verifyConnectionStateIntent(STATE_CONNECTING, STATE_DISCONNECTED);
+ assertThat(mStateMachine.getCurrentState())
+ .isInstanceOf(VolumeControlStateMachine.Connecting.class);
+
+ mLooper.moveTimeForward(VolumeControlStateMachine.CONNECT_TIMEOUT.toMillis());
+ mLooper.dispatchAll();
+
+ verifyConnectionStateIntent(STATE_DISCONNECTED, STATE_CONNECTING);
+ assertThat(mStateMachine.getCurrentState())
+ .isInstanceOf(VolumeControlStateMachine.Disconnected.class);
+
+ verify(mNativeInterface).disconnectVolumeControl(eq(mDevice));
}
- /** Test that an outgoing connection times out */
@Test
- public void testOutgoingTimeout() {
- allowConnection(true);
- doReturn(true)
- .when(mVolumeControlNativeInterface)
- .connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true)
- .when(mVolumeControlNativeInterface)
- .disconnectVolumeControl(any(BluetoothDevice.class));
-
- // Send a connect request
- mVolumeControlStateMachine.sendMessage(VolumeControlStateMachine.CONNECT, mTestDevice);
-
- // Verify that one connection state broadcast is executed
- ArgumentCaptor<Intent> intentArgument1 = ArgumentCaptor.forClass(Intent.class);
- verify(mVolumeControlService, timeout(TIMEOUT_MS).times(1))
- .sendBroadcast(intentArgument1.capture(), anyString());
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTING,
- intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
-
- // Check that we are in Connecting state
- Assert.assertThat(
- mVolumeControlStateMachine.getCurrentState(),
- IsInstanceOf.instanceOf(VolumeControlStateMachine.Connecting.class));
-
- // Verify that one connection state broadcast is executed
- ArgumentCaptor<Intent> intentArgument2 = ArgumentCaptor.forClass(Intent.class);
- verify(
- mVolumeControlService,
- timeout(VolumeControlStateMachine.sConnectTimeoutMs * 2L).times(2))
- .sendBroadcast(intentArgument2.capture(), anyString());
- Assert.assertEquals(
- BluetoothProfile.STATE_DISCONNECTED,
- intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
-
- // Check that we are in Disconnected state
- Assert.assertThat(
- mVolumeControlStateMachine.getCurrentState(),
- IsInstanceOf.instanceOf(VolumeControlStateMachine.Disconnected.class));
- verify(mVolumeControlNativeInterface).disconnectVolumeControl(eq(mTestDevice));
+ public void incomingConnect_whenTimeOut_isDisconnectedAndInAcceptList() {
+ generateConnectionMessageFromNative(STATE_CONNECTING, STATE_DISCONNECTED);
+ assertThat(mStateMachine.getCurrentState())
+ .isInstanceOf(VolumeControlStateMachine.Connecting.class);
+
+ mLooper.moveTimeForward(VolumeControlStateMachine.CONNECT_TIMEOUT.toMillis());
+ mLooper.dispatchAll();
+
+ verifyConnectionStateIntent(STATE_DISCONNECTED, STATE_CONNECTING);
+ assertThat(mStateMachine.getCurrentState())
+ .isInstanceOf(VolumeControlStateMachine.Disconnected.class);
+ verify(mNativeInterface).disconnectVolumeControl(eq(mDevice));
}
- /** Test that an incoming connection times out */
@Test
- public void testIncomingTimeout() {
- allowConnection(true);
- doReturn(true)
- .when(mVolumeControlNativeInterface)
- .connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true)
- .when(mVolumeControlNativeInterface)
- .disconnectVolumeControl(any(BluetoothDevice.class));
+ public void disconnect_whenDisconnected_isDisconnectedWithoutBroadcast() {
+ sendAndDispatchMessage(MESSAGE_DISCONNECT);
+ assertThat(mStateMachine.getCurrentState())
+ .isInstanceOf(VolumeControlStateMachine.Disconnected.class);
+ verify(mService, never()).sendBroadcast(any(), any());
+ }
- // Inject an event for when incoming connection is requested
- VolumeControlStackEvent connStCh =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- connStCh.device = mTestDevice;
- connStCh.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTING;
- mVolumeControlStateMachine.sendMessage(VolumeControlStateMachine.STACK_EVENT, connStCh);
-
- // Verify that one connection state broadcast is executed
- ArgumentCaptor<Intent> intentArgument1 = ArgumentCaptor.forClass(Intent.class);
- verify(mVolumeControlService, timeout(TIMEOUT_MS).times(1))
- .sendBroadcast(intentArgument1.capture(), anyString());
- Assert.assertEquals(
- BluetoothProfile.STATE_CONNECTING,
- intentArgument1.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
-
- // Check that we are in Connecting state
- Assert.assertThat(
- mVolumeControlStateMachine.getCurrentState(),
- IsInstanceOf.instanceOf(VolumeControlStateMachine.Connecting.class));
-
- // Verify that one connection state broadcast is executed
- ArgumentCaptor<Intent> intentArgument2 = ArgumentCaptor.forClass(Intent.class);
- verify(
- mVolumeControlService,
- timeout(VolumeControlStateMachine.sConnectTimeoutMs * 2L).times(2))
- .sendBroadcast(intentArgument2.capture(), anyString());
- Assert.assertEquals(
- BluetoothProfile.STATE_DISCONNECTED,
- intentArgument2.getValue().getIntExtra(BluetoothProfile.EXTRA_STATE, -1));
-
- // Check that we are in Disconnected state
- Assert.assertThat(
- mVolumeControlStateMachine.getCurrentState(),
- IsInstanceOf.instanceOf(VolumeControlStateMachine.Disconnected.class));
- verify(mVolumeControlNativeInterface).disconnectVolumeControl(eq(mTestDevice));
+ @Test
+ public void disconnect_whenConnecting_isDisconnectedWithBroadcast() {
+ sendAndDispatchMessage(MESSAGE_CONNECT);
+ verifyConnectionStateIntent(STATE_CONNECTING, STATE_DISCONNECTED);
+ sendAndDispatchMessage(MESSAGE_CONNECT_TIMEOUT);
+ verifyConnectionStateIntent(STATE_DISCONNECTED, STATE_CONNECTING);
+ assertThat(mStateMachine.getConnectionState()).isEqualTo(STATE_DISCONNECTED);
}
@Test
- public void testStatesChangesWithMessages() {
- allowConnection(true);
- doReturn(true)
- .when(mVolumeControlNativeInterface)
- .connectVolumeControl(any(BluetoothDevice.class));
- doReturn(true)
- .when(mVolumeControlNativeInterface)
- .disconnectVolumeControl(any(BluetoothDevice.class));
-
- // Check that we are in Disconnected state
- Assert.assertThat(
- mVolumeControlStateMachine.getCurrentState(),
- IsInstanceOf.instanceOf(VolumeControlStateMachine.Disconnected.class));
-
- mVolumeControlStateMachine.sendMessage(mVolumeControlStateMachine.DISCONNECT);
- // Check that we are in Disconnected state
- Assert.assertThat(
- mVolumeControlStateMachine.getCurrentState(),
- IsInstanceOf.instanceOf(VolumeControlStateMachine.Disconnected.class));
-
- // disconnected -> connecting
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(mVolumeControlStateMachine.CONNECT),
- VolumeControlStateMachine.Connecting.class);
- // connecting -> disconnected
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(VolumeControlStateMachine.CONNECT_TIMEOUT),
- VolumeControlStateMachine.Disconnected.class);
-
- // disconnected -> connecting
- VolumeControlStackEvent stackEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- stackEvent.device = mTestDevice;
- stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTING;
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(
- mVolumeControlStateMachine.STACK_EVENT, stackEvent),
- VolumeControlStateMachine.Connecting.class);
-
- // connecting -> disconnected
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(mVolumeControlStateMachine.DISCONNECT),
- VolumeControlStateMachine.Disconnected.class);
-
- // disconnected -> connecting
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(mVolumeControlStateMachine.CONNECT),
- VolumeControlStateMachine.Connecting.class);
- // connecting -> disconnecting
- stackEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- stackEvent.device = mTestDevice;
- stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTING;
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(
- mVolumeControlStateMachine.STACK_EVENT, stackEvent),
- VolumeControlStateMachine.Disconnecting.class);
- // disconnecting -> connecting
- stackEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- stackEvent.device = mTestDevice;
- stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTING;
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(
- mVolumeControlStateMachine.STACK_EVENT, stackEvent),
- VolumeControlStateMachine.Connecting.class);
- // connecting -> connected
- stackEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- stackEvent.device = mTestDevice;
- stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTED;
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(
- mVolumeControlStateMachine.STACK_EVENT, stackEvent),
- VolumeControlStateMachine.Connected.class);
- // connected -> disconnecting
- stackEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- stackEvent.device = mTestDevice;
- stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTING;
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(
- mVolumeControlStateMachine.STACK_EVENT, stackEvent),
- VolumeControlStateMachine.Disconnecting.class);
- // disconnecting -> disconnected
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(VolumeControlStateMachine.CONNECT_TIMEOUT),
- VolumeControlStateMachine.Disconnected.class);
-
- // disconnected -> connected
- stackEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- stackEvent.device = mTestDevice;
- stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTED;
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(
- mVolumeControlStateMachine.STACK_EVENT, stackEvent),
- VolumeControlStateMachine.Connected.class);
- // connected -> disconnected
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(mVolumeControlStateMachine.DISCONNECT),
- VolumeControlStateMachine.Disconnecting.class);
-
- // disconnecting -> connected
- stackEvent =
- new VolumeControlStackEvent(
- VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- stackEvent.device = mTestDevice;
- stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_CONNECTED;
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(
- mVolumeControlStateMachine.STACK_EVENT, stackEvent),
- VolumeControlStateMachine.Connected.class);
- // connected -> disconnected
- stackEvent =
+ public void disconnect_whenIncomingConnecting_isDisconnectedWithBroadcast() {
+ generateConnectionMessageFromNative(STATE_CONNECTING, STATE_DISCONNECTED);
+ sendAndDispatchMessage(MESSAGE_DISCONNECT);
+ verifyConnectionStateIntent(STATE_DISCONNECTED, STATE_CONNECTING);
+ assertThat(mStateMachine.getConnectionState()).isEqualTo(STATE_DISCONNECTED);
+ }
+
+ @Test
+ public void timeout_whenDisconnecting_isDisconnected() {
+ sendAndDispatchMessage(MESSAGE_CONNECT);
+ generateConnectionMessageFromNative(STATE_CONNECTING, STATE_DISCONNECTED);
+ generateConnectionMessageFromNative(STATE_DISCONNECTING, STATE_CONNECTING);
+ generateConnectionMessageFromNative(STATE_CONNECTING, STATE_DISCONNECTING);
+ generateConnectionMessageFromNative(STATE_CONNECTED, STATE_CONNECTING);
+ generateConnectionMessageFromNative(STATE_DISCONNECTING, STATE_CONNECTED);
+ sendAndDispatchMessage(MESSAGE_CONNECT_TIMEOUT);
+ verifyConnectionStateIntent(STATE_DISCONNECTED, STATE_DISCONNECTING);
+ assertThat(mStateMachine.getConnectionState()).isEqualTo(STATE_DISCONNECTED);
+ }
+
+ @Test
+ public void incomingConnect_whenDisconnected_isConnected() {
+ generateConnectionMessageFromNative(STATE_CONNECTED, STATE_DISCONNECTED);
+ assertThat(mStateMachine.getConnectionState()).isEqualTo(STATE_CONNECTED);
+ }
+
+ @Test
+ public void incomingConnect_whenDisconnecting_isConnected() {
+ generateConnectionMessageFromNative(STATE_CONNECTING, STATE_DISCONNECTED);
+ generateConnectionMessageFromNative(STATE_CONNECTED, STATE_CONNECTING);
+ sendAndDispatchMessage(MESSAGE_DISCONNECT);
+
+ assertThat(mStateMachine.getConnectionState()).isEqualTo(STATE_DISCONNECTING);
+
+ generateConnectionMessageFromNative(STATE_CONNECTED, STATE_DISCONNECTING);
+ assertThat(mStateMachine.getConnectionState()).isEqualTo(STATE_CONNECTED);
+ }
+
+ private void sendAndDispatchMessage(int what, Object obj) {
+ mStateMachine.sendMessage(what, obj);
+ mLooper.dispatchAll();
+ }
+
+ private void sendAndDispatchMessage(int what) {
+ sendAndDispatchMessage(what, null);
+ }
+
+ @SafeVarargs
+ private void verifyIntentSent(Matcher<Intent>... matchers) {
+ mInOrder.verify(mService)
+ .sendBroadcast(MockitoHamcrest.argThat(AllOf.allOf(matchers)), any());
+ }
+
+ private void verifyConnectionStateIntent(int newState, int oldState) {
+ verifyIntentSent(
+ hasAction(ACTION_CONNECTION_STATE_CHANGED),
+ hasExtra(BluetoothDevice.EXTRA_DEVICE, mDevice),
+ hasExtra(EXTRA_STATE, newState),
+ hasExtra(EXTRA_PREVIOUS_STATE, oldState));
+ assertThat(mStateMachine.getConnectionState()).isEqualTo(newState);
+ }
+
+ private void generateConnectionMessageFromNative(int newState, int oldState) {
+ VolumeControlStackEvent event =
new VolumeControlStackEvent(
VolumeControlStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- stackEvent.device = mTestDevice;
- stackEvent.valueInt1 = VolumeControlStackEvent.CONNECTION_STATE_DISCONNECTED;
- sendMessageAndVerifyTransition(
- mVolumeControlStateMachine.obtainMessage(
- VolumeControlStateMachine.STACK_EVENT, stackEvent),
- VolumeControlStateMachine.Disconnected.class);
- }
+ event.device = mDevice;
+ event.valueInt1 = newState;
- private <T> void sendMessageAndVerifyTransition(Message msg, Class<T> type) {
- Mockito.clearInvocations(mVolumeControlService);
- mVolumeControlStateMachine.sendMessage(msg);
- // Verify that one connection state broadcast is executed
- verify(mVolumeControlService, timeout(TIMEOUT_MS).times(1))
- .sendBroadcast(any(Intent.class), anyString());
- Assert.assertThat(
- mVolumeControlStateMachine.getCurrentState(), IsInstanceOf.instanceOf(type));
+ sendAndDispatchMessage(MESSAGE_STACK_EVENT, event);
+ verifyConnectionStateIntent(newState, oldState);
}
}
diff --git a/android/pandora/mmi2grpc/mmi2grpc/vcp.py b/android/pandora/mmi2grpc/mmi2grpc/vcp.py
index 905f551916..fa869abbb6 100644
--- a/android/pandora/mmi2grpc/mmi2grpc/vcp.py
+++ b/android/pandora/mmi2grpc/mmi2grpc/vcp.py
@@ -17,23 +17,33 @@ import threading
from mmi2grpc._helpers import assert_description, match_description
from mmi2grpc._proxy import ProfileProxy
from mmi2grpc._rootcanal import Dongle
+
+from pandora_experimental.vcp_grpc import VCP
+from pandora_experimental.gatt_grpc import GATT
+from pandora.security_grpc import Security, SecurityStorage
+from pandora.security_pb2 import LE_LEVEL3, PairingEventAnswer
from pandora.host_grpc import Host
from pandora.host_pb2 import PUBLIC, RANDOM
from pandora.security_grpc import Security
from pandora.security_pb2 import LE_LEVEL3, PairingEventAnswer
from pandora_experimental.le_audio_grpc import LeAudio
+from time import sleep
+
class VCPProxy(ProfileProxy):
def __init__(self, channel, rootcanal):
super().__init__(channel)
+ self.vcp = VCP(channel)
+ self.gatt = GATT(channel)
+ self.security_storage = SecurityStorage(channel)
self.host = Host(channel)
self.security = Security(channel)
self.le_audio = LeAudio(channel)
self.rootcanal = rootcanal
self.connection = None
- self.pairing_stream = None
+ self.pairing_stream = self.security.OnPairing()
def test_started(self, test: str, description: str, pts_addr: bytes):
self.rootcanal.select_pts_dongle(Dongle.LAIRD_BL654)
@@ -49,13 +59,18 @@ class VCPProxy(ProfileProxy):
the Implementation Under Test (IUT) can initiate a GATT connect request
to the PTS.
"""
+ self.security_storage.DeleteBond(public=pts_addr)
self.connection = self.host.ConnectLE(own_address_type=RANDOM, public=pts_addr).connection
- self.pairing_stream = self.security.OnPairing()
def secure():
self.security.Secure(connection=self.connection, le=LE_LEVEL3)
+ def vcp_connect():
+ self.vcp.WaitConnect(connection=self.connection)
+
threading.Thread(target=secure).start()
+ threading.Thread(target=vcp_connect).start()
+
return "OK"
@match_description
@@ -80,10 +95,14 @@ class VCPProxy(ProfileProxy):
"""
Please take action to discover the
(Volume Control Point|Volume State|Volume Flags|Offset State|Volume Offset Control Point)
- characteristic from the Volume (Offset)? Control. Discover the primary service if needed.
+ characteristic from the Volume (Offset )?Control. Discover the primary service if needed.
Description: Verify that the Implementation Under Test \(IUT\) can send
Discover All Characteristics command.
"""
+ # PTS expects us to do discovery after bonding, but in fact Android does it as soon as
+ # encryption is completed. Invalidate GATT cache so the discovery takes place again
+ self.gatt.ClearCache(connection=self.connection)
+
return "OK"
@match_description
@@ -92,13 +111,26 @@ class VCPProxy(ProfileProxy):
Please send Read Request to read (?P<name>(Volume State|Volume Flags|Offset State)) characteristic with handle
= (?P<handle>(0x[0-9A-Fa-f]{4})).
"""
+ # After discovery Android reads these values by itself, after profile connection.
+ # Although, for some tests, this is used as validation, for example for tests with invalid
+ # behavior (BI tests). Just send GATT read to sattisfy this conditions, as VCP has no exposed
+ # (or even existing, native) interface to trigger read on demand.
+ def read():
+ nonlocal handle
+ self.gatt.ReadCharacteristicFromHandle(\
+ connection=self.connection, handle=int(handle, base=16))
+
+ worker = threading.Thread(target=read)
+ worker.start()
+ worker.join(timeout=30)
+
return "OK"
- @assert_description
- def USER_CONFIRM_SUPPORTED_CHARACTERISTIC(self, characteristics: str, **kwargs):
+ @match_description
+ def USER_CONFIRM_SUPPORTED_CHARACTERISTIC(self, body: str, **kwargs):
"""
Please verify that for each supported characteristic, attribute
- handle/UUID pair(s) is returned to the upper tester.(?P<characteristics>(.|\n)*)
+ handle/UUID pair\(s\) is returned to the (.*)\.(?P<body>.*)
"""
return "OK"
@@ -109,6 +141,38 @@ class VCPProxy(ProfileProxy):
Please write to Client Characteristic Configuration Descriptor of
(?P<name>(Volume State|Offset State)) characteristic to enable notification.
"""
+
+ # After discovery Android subscribes by itself, after profile connection
+ return "OK"
+
+ def IUT_SEND_WRITE_REQUEST(self, description: str, **kwargs):
+ r"""
+ Please send write request to handle 0xXXXX with following value.
+ Characteristic name:
+ Op Code: [X (0xXX)] Op code name
+ Change Counter: <WildCard: Exists>
+ Value: <WildCard: Exists>
+ """
+
+ # Wait a couple seconds so the VCP is ready (subscriptions and reads are completed)
+ sleep(2)
+
+ if ("Set Absolute Volume" in description):
+ self.vcp.SetDeviceVolume(connection=self.connection, volume=42)
+ elif ("Unmute" in description):
+ # for now, there is no way to trigger this, and tests are skipped
+ return "No"
+ elif ("Set Volume Offset" in description):
+ self.vcp.SetVolumeOffset(connection=self.connection, offset=42)
+ elif ("Volume Control Point" in description and
+ "Op Code: <WildCard: Exists>" in description):
+ # Handles sending *any* OP Code on Volume Control Point
+ self.vcp.SetDeviceVolume(connection=self.connection, volume=42)
+ elif ("Volume Offset Control Point" in description and
+ "Op Code: <WildCard: Exists>" in description):
+ self.vcp.SetVolumeOffset(connection=self.connection, offset=42)
+
+
return "OK"
@assert_description
diff --git a/android/pandora/server/configs/pts_bot_tests_config.json b/android/pandora/server/configs/pts_bot_tests_config.json
index 3cfbe0d26e..45b8679572 100644
--- a/android/pandora/server/configs/pts_bot_tests_config.json
+++ b/android/pandora/server/configs/pts_bot_tests_config.json
@@ -686,7 +686,19 @@
"SM/PER/SCJW/BV-03-C",
"SM/PER/SCPK/BI-03-C",
"SM/PER/SCPK/BV-02-C",
- "VCP/VC/CGGIT/CHA/BV-06-C"
+ "VCP/VC/CGGIT/CHA/BV-01-C",
+ "VCP/VC/CGGIT/CHA/BV-02-C",
+ "VCP/VC/CGGIT/CHA/BV-03-C",
+ "VCP/VC/CGGIT/CHA/BV-04-C",
+ "VCP/VC/CGGIT/CHA/BV-06-C",
+ "VCP/VC/CGGIT/SER/BV-01-C",
+ "VCP/VC/CGGIT/SER/BV-02-C",
+ "VCP/VC/SPE/BI-05-C",
+ "VCP/VC/SPE/BI-13-C",
+ "VCP/VC/SPE/BI-15-C",
+ "VCP/VC/SPE/BI-16-C",
+ "VCP/VC/VCCP/BV-05-C",
+ "VCP/VC/VOCP/BV-01-C"
],
"flaky": [
"A2DP/SRC/SUS/BV-02-I",
@@ -1145,20 +1157,8 @@
"SM/PER/SCPK/BV-03-C",
"SM/PER/SIE/BV-01-C",
"SM/PER/SIP/BV-01-C",
- "VCP/VC/CGGIT/CHA/BV-01-C",
- "VCP/VC/CGGIT/CHA/BV-02-C",
- "VCP/VC/CGGIT/CHA/BV-03-C",
- "VCP/VC/CGGIT/CHA/BV-04-C",
- "VCP/VC/CGGIT/SER/BV-01-C",
- "VCP/VC/CGGIT/SER/BV-02-C",
- "VCP/VC/SPE/BI-05-C",
"VCP/VC/SPE/BI-06-C",
- "VCP/VC/SPE/BI-13-C",
- "VCP/VC/SPE/BI-15-C",
- "VCP/VC/SPE/BI-16-C",
- "VCP/VC/VCCP/BV-05-C",
- "VCP/VC/VCCP/BV-06-C",
- "VCP/VC/VOCP/BV-01-C"
+ "VCP/VC/VCCP/BV-06-C"
],
"ics": {
"TSPC_4.0HCI_1_1": true,
@@ -3168,7 +3168,8 @@
"SM": {},
"SPP": {},
"SUM ICS": {},
- "VCP": {}
+ "VCP": {
+ }
},
"flags": [
{
diff --git a/android/pandora/server/src/Server.kt b/android/pandora/server/src/Server.kt
index 79993339e9..54830fd4e5 100644
--- a/android/pandora/server/src/Server.kt
+++ b/android/pandora/server/src/Server.kt
@@ -68,6 +68,7 @@ class Server(context: Context) {
BluetoothProfile.OPP to ::Opp,
BluetoothProfile.MAP to ::Map,
BluetoothProfile.LE_AUDIO to ::LeAudio,
+ BluetoothProfile.VOLUME_CONTROL to ::Vcp,
)
.filter { bluetoothAdapter.isEnabled }
.filter { bluetoothAdapter.getSupportedProfiles().contains(it.key) == true }
diff --git a/android/pandora/server/src/Vcp.kt b/android/pandora/server/src/Vcp.kt
new file mode 100644
index 0000000000..c8aa8c5802
--- /dev/null
+++ b/android/pandora/server/src/Vcp.kt
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2024 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.pandora
+
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothDevice.TRANSPORT_LE
+import android.bluetooth.BluetoothVolumeControl
+import android.bluetooth.BluetoothManager
+import android.bluetooth.BluetoothProfile
+import android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.util.Log
+import com.google.protobuf.Empty
+import io.grpc.Status
+import io.grpc.stub.StreamObserver
+import java.io.Closeable
+import java.io.PrintWriter
+import java.io.StringWriter
+import java.util.concurrent.Executors
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.shareIn
+import pandora.vcp.VCPGrpc.VCPImplBase
+import pandora.vcp.VcpProto.*
+import pandora.HostProto.Connection
+
+@kotlinx.coroutines.ExperimentalCoroutinesApi
+class Vcp(val context: Context) : VCPImplBase(), Closeable {
+ private val TAG = "PandoraVcp"
+
+ private val scope: CoroutineScope = CoroutineScope(Dispatchers.Default.limitedParallelism(1))
+
+ private val bluetoothManager = context.getSystemService(BluetoothManager::class.java)!!
+ private val bluetoothAdapter = bluetoothManager.adapter
+
+ private val bluetoothVolumeControl =
+ getProfileProxy<BluetoothVolumeControl>(context, BluetoothProfile.VOLUME_CONTROL)
+
+ private val flow =
+ intentFlow(
+ context,
+ IntentFilter().apply {
+ addAction(BluetoothVolumeControl.ACTION_CONNECTION_STATE_CHANGED)
+ },
+ scope,
+ )
+ .shareIn(scope, SharingStarted.Eagerly)
+
+ override fun close() {
+ // Deinit the CoroutineScope
+ scope.cancel()
+ }
+
+ override fun setDeviceVolume(
+ request: SetDeviceVolumeRequest,
+ responseObserver: StreamObserver<Empty>
+ ) {
+ grpcUnary<Empty>(scope, responseObserver) {
+ val device = request.connection.toBluetoothDevice(bluetoothAdapter)
+
+ Log.i(TAG, "setDeviceVolume(${device}, ${request.volume})")
+
+ bluetoothVolumeControl.setDeviceVolume(device, request.volume, false)
+
+ Empty.getDefaultInstance()
+ }
+ }
+
+ override fun setVolumeOffset(
+ request: SetVolumeOffsetRequest,
+ responseObserver: StreamObserver<Empty>
+ ) {
+ grpcUnary<Empty>(scope, responseObserver) {
+ val device = request.connection.toBluetoothDevice(bluetoothAdapter)
+
+ Log.i(TAG, "setVolumeOffset(${device}, ${request.offset})")
+
+ bluetoothVolumeControl.setVolumeOffset(device, 1, request.offset)
+
+ Empty.getDefaultInstance()
+ }
+ }
+
+ override fun waitConnect(
+ request: WaitConnectRequest,
+ responseObserver: StreamObserver<Empty>
+ ) {
+ grpcUnary<Empty>(scope, responseObserver) {
+ val device = request.connection.toBluetoothDevice(bluetoothAdapter)
+ Log.i(TAG, "waitPeripheral(${device}")
+ if (
+ bluetoothVolumeControl.getConnectionState(device) != BluetoothProfile.STATE_CONNECTED
+ ) {
+ Log.d(TAG, "Manual call to setConnectionPolicy")
+ bluetoothVolumeControl.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED)
+ Log.d(TAG, "wait for bluetoothVolumeControl profile connection")
+ flow
+ .filter { it.getBluetoothDeviceExtra() == device }
+ .map { it.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR) }
+ .filter { it == BluetoothProfile.STATE_CONNECTED }
+ .first()
+ }
+
+ Empty.getDefaultInstance()
+ }
+ }
+} \ No newline at end of file
diff --git a/android/pandora/test/Android.bp b/android/pandora/test/Android.bp
index 0b75292c3c..cc961871a7 100644
--- a/android/pandora/test/Android.bp
+++ b/android/pandora/test/Android.bp
@@ -39,9 +39,11 @@ python_test_host {
unit_test: false,
},
data: [
- ":PandoraServer",
"config.yml",
],
+ device_common_data: [
+ ":PandoraServer",
+ ],
}
python_test_host {
@@ -68,9 +70,11 @@ python_test_host {
unit_test: false,
},
data: [
- ":PandoraServer",
"config.yml",
],
+ device_common_data: [
+ ":PandoraServer",
+ ],
}
sh_binary_host {
diff --git a/flags/Android.bp b/flags/Android.bp
index db47305e1e..f08db2fb78 100644
--- a/flags/Android.bp
+++ b/flags/Android.bp
@@ -7,6 +7,9 @@ aconfig_declarations {
name: "bluetooth_aconfig_flags",
package: "com.android.bluetooth.flags",
container: "com.android.btservices",
+ visibility: [
+ "//packages/modules/Bluetooth/framework",
+ ],
// LINT.IfChange
srcs: [
"a2dp.aconfig",
@@ -60,11 +63,7 @@ java_aconfig_library {
aconfig_declarations: "bluetooth_aconfig_flags",
visibility: [
"//cts/tests/tests/bluetooth:__subpackages__",
- "//packages/modules/Bluetooth/android/app",
- "//packages/modules/Bluetooth/framework",
- "//packages/modules/Bluetooth/framework/tests/bumble",
- "//packages/modules/Bluetooth/framework/tests/util",
- "//packages/modules/Bluetooth/service:__subpackages__",
+ "//packages/modules/Bluetooth:__subpackages__",
],
apex_available: [
"com.android.btservices",
diff --git a/flags/a2dp.aconfig b/flags/a2dp.aconfig
index 2026a47446..ba1943b944 100644
--- a/flags/a2dp.aconfig
+++ b/flags/a2dp.aconfig
@@ -147,3 +147,14 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+
+flag {
+ name: "a2dp_source_threading_fix"
+ namespace: "bluetooth"
+ description: "Schedule A2DP source setup operations to bt_main_thread to prevent races"
+ bug: "374166531"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/flags/active_device_manager.aconfig b/flags/active_device_manager.aconfig
index dcbd6c154c..fefcdd1d87 100644
--- a/flags/active_device_manager.aconfig
+++ b/flags/active_device_manager.aconfig
@@ -29,4 +29,14 @@ flag {
metadata {
purpose: PURPOSE_BUGFIX
}
+}
+
+flag {
+ name: "adm_fix_disconnect_of_set_member"
+ namespace: "bluetooth"
+ description: "Fix disconnecting of the set member device. Make sure the other set member is not considered as fallback device."
+ bug: "374320313"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
} \ No newline at end of file
diff --git a/flags/avrcp.aconfig b/flags/avrcp.aconfig
index 8a6a553b34..1c50da0949 100644
--- a/flags/avrcp.aconfig
+++ b/flags/avrcp.aconfig
@@ -50,3 +50,10 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "avrcp_16_default"
+ namespace: "bluetooth"
+ description: "Set AVRCP 1.6 as default AVRCP version"
+ bug: "374271695"
+}
diff --git a/flags/framework.aconfig b/flags/framework.aconfig
index 7834bfd524..32b88d447a 100644
--- a/flags/framework.aconfig
+++ b/flags/framework.aconfig
@@ -63,3 +63,21 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "support_remote_device_metadata"
+ is_exported: true
+ namespace: "bluetooth"
+ description: "Support setting/retrieving the remote device metadata for a BluetoothDevice"
+ bug: "374171574"
+}
+
+flag {
+ name: "fix_add_device_properties"
+ namespace: "bluetooth"
+ description: "Make sure single entry for mDevices. Race fix."
+ bug: "375158716"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+} \ No newline at end of file
diff --git a/flags/gap.aconfig b/flags/gap.aconfig
index 396b5a496b..2b2b5cdd55 100644
--- a/flags/gap.aconfig
+++ b/flags/gap.aconfig
@@ -30,13 +30,6 @@ flag {
}
flag {
- name: "le_scan_fix_remote_exception"
- namespace: "bluetooth"
- description: "Fix handling remote exception for LE scanners"
- bug: "320402249"
-}
-
-flag {
name: "gatt_fix_device_busy"
namespace: "bluetooth"
description: "Fix device busy bug in BluetoothGatt"
@@ -254,3 +247,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "le_scan_remove_non_oneway_binder_calls"
+ namespace: "bluetooth"
+ description: "Remove non-oneway binder calls from BluetoothLeScanner.startScan"
+ bug: "375558872"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/flags/leaudio.aconfig b/flags/leaudio.aconfig
index 02361f1b6b..346c3ba154 100644
--- a/flags/leaudio.aconfig
+++ b/flags/leaudio.aconfig
@@ -391,3 +391,29 @@ flag {
description: "API to get and set microphone for call enable status"
bug: "372395197"
}
+
+flag {
+ name: "leaudio_broadcast_primary_group_selection"
+ namespace: "bluetooth"
+ description: "Fix race condition in primary group selection"
+ bug: "375422795"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
+ name: "leaudio_broadcast_api_get_local_metadata"
+ is_exported: true
+ namespace: "bluetooth"
+ description: "API to get broadcast assistant local metadata"
+ bug: "375423982"
+}
+
+flag {
+ name: "leaudio_broadcast_api_manage_primary_group"
+ is_exported: true
+ namespace: "bluetooth"
+ description: "API to manage broadcast primary group"
+ bug: "375422410"
+}
diff --git a/flags/pairing.aconfig b/flags/pairing.aconfig
index 8acd9afbc7..66ab03984c 100644
--- a/flags/pairing.aconfig
+++ b/flags/pairing.aconfig
@@ -12,13 +12,6 @@ flag {
}
flag {
- name: "cleanup_le_only_device_type"
- namespace: "bluetooth"
- description: "Cleanup the duplicate bond records only if the device type is LE-only"
- bug: "333949759"
-}
-
-flag {
name: "pairing_on_unknown_transport"
namespace: "bluetooth"
description: "Allow pairing on transport not known to be supported by the remote device"
diff --git a/flags/sockets.aconfig b/flags/sockets.aconfig
index d0ba2d2a5f..b27b6a53fd 100644
--- a/flags/sockets.aconfig
+++ b/flags/sockets.aconfig
@@ -44,3 +44,11 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "socket_settings_api"
+ namespace: "bluetooth"
+ description: "Adds new socket settings interface which allows creation of encryption only socket"
+ bug: "374358112"
+ is_exported: true
+}
diff --git a/floss/hcidoc/packets/build.rs b/floss/hcidoc/packets/build.rs
index 7a08060feb..f9d0304a55 100644
--- a/floss/hcidoc/packets/build.rs
+++ b/floss/hcidoc/packets/build.rs
@@ -44,7 +44,7 @@ fn generate_packets() {
);
let out_file = File::create(out_dir.join("hci_packets.rs")).unwrap();
- let in_file = PathBuf::from("../../../system/pdl/hci/hci_packets.pdl");
+ let in_file = PathBuf::from("../../../tools/rootcanal/packets/hci_packets.pdl");
println!("cargo:rerun-if-changed={}", in_file.display());
let output = Command::new("pdlc")
diff --git a/floss/hcidoc/packets/lib.rs b/floss/hcidoc/packets/lib.rs
index af9d810145..4a71e58e13 100644
--- a/floss/hcidoc/packets/lib.rs
+++ b/floss/hcidoc/packets/lib.rs
@@ -36,4 +36,46 @@ pub mod hci {
bytes[0..6].try_into().unwrap()
}
}
+
+ pub struct GapData {
+ pub data_type: GapDataType,
+ pub data: Vec<u8>,
+ }
+
+ impl GapData {
+ pub fn parse(bytes: &[u8]) -> std::result::Result<Self, String> {
+ // In case of parsing EIR, we can get normal data, or all zeroes. Normal data always
+ // have at least 2 bytes: one for the length, and another for the type. Therefore we
+ // can terminate early if the data has less than 2 bytes.
+ if (bytes.len() == 0) {
+ return Err("no data to parse".to_string());
+ } else if (bytes.len() == 1) {
+ if (bytes[0] != 0) {
+ return Err(format!("can't parse 1 byte of data: {}", bytes[0]));
+ }
+ return Ok(GapData { data_type: GapDataType::Invalid, data: vec![] });
+ }
+
+ let mut data_size = bytes[0] as usize;
+ if (data_size == 0) {
+ // Data size already include the data_type, so size = 0 is possible only when
+ // parsing EIR, where all data are zeroes. Here we just assume that assumption is
+ // correct, and don't really check all the elements.
+ return Ok(GapData { data_type: GapDataType::Invalid, data: bytes[2..].to_vec() });
+ }
+
+ if (data_size > bytes.len() - 1) {
+ return Err(format!(
+ "size {} is bigger than remaining length {}",
+ data_size,
+ bytes.len() - 1
+ ));
+ }
+ let data_type = match GapDataType::try_from(bytes[1]) {
+ Ok(data_type) => Ok(data_type),
+ Err(_) => Err(format!("can't parse data type {}", bytes[1])),
+ }?;
+ return Ok(GapData { data_type, data: bytes[2..(data_size + 1)].to_vec() });
+ }
+ }
}
diff --git a/floss/hcidoc/src/groups/connections.rs b/floss/hcidoc/src/groups/connections.rs
index 9c1526f1b7..0f22e73e5f 100644
--- a/floss/hcidoc/src/groups/connections.rs
+++ b/floss/hcidoc/src/groups/connections.rs
@@ -8,11 +8,9 @@ use std::slice::Iter;
use crate::engine::{Rule, RuleGroup, Signal};
use crate::parser::{Packet, PacketChild};
use hcidoc_packets::hci::{
- Acl, AclCommandChild, Address, AuthenticatedPayloadTimeoutExpired, CommandChild,
- ConnectionManagementCommandChild, DisconnectReason, Enable, ErrorCode, EventChild,
- InitiatorFilterPolicy, LeConnectionManagementCommandChild, LeMetaEventChild,
- LeSecurityCommandChild, NumberOfCompletedPackets, OpCode, ScoConnectionCommandChild,
- SecurityCommandChild,
+ Acl, Address, AuthenticatedPayloadTimeoutExpired, CommandChild, DisconnectReason, Enable,
+ ErrorCode, EventChild, InitiatorFilterPolicy, LeMetaEventChild, NumberOfCompletedPackets,
+ OpCode,
};
enum ConnectionSignal {
@@ -626,100 +624,77 @@ impl Rule for OddDisconnectionsRule {
fn process(&mut self, packet: &Packet) {
match &packet.inner {
PacketChild::HciCommand(cmd) => match cmd.specialize() {
- CommandChild::AclCommand(aclpkt) => match aclpkt.specialize() {
- AclCommandChild::ConnectionManagementCommand(conn) => match conn.specialize() {
- ConnectionManagementCommandChild::CreateConnection(cc) => {
- self.process_classic_connection(cc.get_bd_addr(), packet);
- }
- ConnectionManagementCommandChild::AcceptConnectionRequest(ac) => {
- self.process_classic_connection(ac.get_bd_addr(), packet);
- }
- ConnectionManagementCommandChild::ReadRemoteSupportedFeatures(rrsf) => {
- self.process_remote_feat_cmd(
- PendingRemoteFeature::Supported,
- &rrsf.get_connection_handle(),
- packet,
- );
- }
- ConnectionManagementCommandChild::ReadRemoteExtendedFeatures(rref) => {
- self.process_remote_feat_cmd(
- PendingRemoteFeature::Extended,
- &rref.get_connection_handle(),
- packet,
- );
- }
- // End ConnectionManagementCommand.specialize()
- _ => {}
- },
- AclCommandChild::ScoConnectionCommand(sco_con) => match sco_con.specialize() {
- ScoConnectionCommandChild::SetupSynchronousConnection(ssc) => {
- let address =
- self.convert_sco_handle_to_address(ssc.get_connection_handle());
- self.process_sync_connection(address, packet);
- }
- ScoConnectionCommandChild::EnhancedSetupSynchronousConnection(esc) => {
- let address =
- self.convert_sco_handle_to_address(esc.get_connection_handle());
- self.process_sync_connection(address, packet);
- }
- ScoConnectionCommandChild::AcceptSynchronousConnection(asc) => {
- self.process_sync_connection(asc.get_bd_addr(), packet);
- }
- ScoConnectionCommandChild::EnhancedAcceptSynchronousConnection(easc) => {
- self.process_sync_connection(easc.get_bd_addr(), packet);
- }
- // End ScoConnectionCommand.specialize()
- _ => {}
- },
- AclCommandChild::LeConnectionManagementCommand(le_conn) => match le_conn
- .specialize()
- {
- LeConnectionManagementCommandChild::LeCreateConnection(lcc) => {
- self.process_le_create_connection(
- lcc.get_peer_address(),
- lcc.get_initiator_filter_policy(),
- packet,
- );
- }
- LeConnectionManagementCommandChild::LeExtendedCreateConnection(lecc) => {
- self.process_le_create_connection(
- lecc.get_peer_address(),
- lecc.get_initiator_filter_policy(),
- packet,
- );
- }
- LeConnectionManagementCommandChild::LeAddDeviceToFilterAcceptList(laac) => {
- self.process_add_accept_list(laac.get_address(), packet);
- }
- LeConnectionManagementCommandChild::LeRemoveDeviceFromFilterAcceptList(
- lrac,
- ) => {
- self.process_remove_accept_list(lrac.get_address(), packet);
- }
- LeConnectionManagementCommandChild::LeClearFilterAcceptList(_lcac) => {
- self.process_clear_accept_list(packet);
- }
- LeConnectionManagementCommandChild::LeReadRemoteFeatures(lrrf) => {
- self.process_remote_feat_cmd(
- PendingRemoteFeature::Le,
- &lrrf.get_connection_handle(),
- packet,
- );
- }
- // End LeConnectionManagementCommand.specialize()
- _ => {}
- },
- AclCommandChild::Disconnect(dc_conn) => {
- self.process_disconnect_cmd(
- dc_conn.get_reason(),
- dc_conn.get_connection_handle(),
- packet,
- );
- }
-
- // End AclCommand.specialize()
- _ => (),
- },
+ CommandChild::CreateConnection(cc) => {
+ self.process_classic_connection(cc.get_bd_addr(), packet);
+ }
+ CommandChild::AcceptConnectionRequest(ac) => {
+ self.process_classic_connection(ac.get_bd_addr(), packet);
+ }
+ CommandChild::ReadRemoteSupportedFeatures(rrsf) => {
+ self.process_remote_feat_cmd(
+ PendingRemoteFeature::Supported,
+ &rrsf.get_connection_handle(),
+ packet,
+ );
+ }
+ CommandChild::ReadRemoteExtendedFeatures(rref) => {
+ self.process_remote_feat_cmd(
+ PendingRemoteFeature::Extended,
+ &rref.get_connection_handle(),
+ packet,
+ );
+ }
+ CommandChild::SetupSynchronousConnection(ssc) => {
+ let address = self.convert_sco_handle_to_address(ssc.get_connection_handle());
+ self.process_sync_connection(address, packet);
+ }
+ CommandChild::EnhancedSetupSynchronousConnection(esc) => {
+ let address = self.convert_sco_handle_to_address(esc.get_connection_handle());
+ self.process_sync_connection(address, packet);
+ }
+ CommandChild::AcceptSynchronousConnection(asc) => {
+ self.process_sync_connection(asc.get_bd_addr(), packet);
+ }
+ CommandChild::EnhancedAcceptSynchronousConnection(easc) => {
+ self.process_sync_connection(easc.get_bd_addr(), packet);
+ }
+ CommandChild::LeCreateConnection(lcc) => {
+ self.process_le_create_connection(
+ lcc.get_peer_address(),
+ lcc.get_initiator_filter_policy(),
+ packet,
+ );
+ }
+ CommandChild::LeExtendedCreateConnection(lecc) => {
+ self.process_le_create_connection(
+ lecc.get_peer_address(),
+ lecc.get_initiator_filter_policy(),
+ packet,
+ );
+ }
+ CommandChild::LeAddDeviceToFilterAcceptList(laac) => {
+ self.process_add_accept_list(laac.get_address(), packet);
+ }
+ CommandChild::LeRemoveDeviceFromFilterAcceptList(lrac) => {
+ self.process_remove_accept_list(lrac.get_address(), packet);
+ }
+ CommandChild::LeClearFilterAcceptList(_lcac) => {
+ self.process_clear_accept_list(packet);
+ }
+ CommandChild::LeReadRemoteFeatures(lrrf) => {
+ self.process_remote_feat_cmd(
+ PendingRemoteFeature::Le,
+ &lrrf.get_connection_handle(),
+ packet,
+ );
+ }
+ CommandChild::Disconnect(dc_conn) => {
+ self.process_disconnect_cmd(
+ dc_conn.get_reason(),
+ dc_conn.get_connection_handle(),
+ packet,
+ );
+ }
CommandChild::Reset(_) => {
self.process_reset();
}
@@ -754,6 +729,7 @@ impl Rule for OddDisconnectionsRule {
EventChild::NumberOfCompletedPackets(nocp) => {
self.process_nocp(&nocp, packet);
}
+
EventChild::AuthenticatedPayloadTimeoutExpired(apte) => {
self.process_apte(&apte, packet);
}
@@ -1008,44 +984,26 @@ impl Rule for LinkKeyMismatchRule {
},
PacketChild::HciCommand(cmd) => match cmd.specialize() {
- CommandChild::AclCommand(cmd) => match cmd.specialize() {
- // Have an arm for Disconnect since sometimes we don't receive disconnect
- // event when powering off. However, no need to actually match the reason
- // since we just clean the handle in both cases.
- AclCommandChild::Disconnect(cmd) => {
- self.process_handle_auth(
- ErrorCode::Success,
- cmd.get_connection_handle(),
- &packet,
- );
- self.handles.remove(&cmd.get_connection_handle());
- }
-
- // CommandChild::AclCommand(cmd).specialize()
- _ => {}
- },
-
- CommandChild::SecurityCommand(cmd) => match cmd.specialize() {
- SecurityCommandChild::LinkKeyRequestReply(cmd) => {
- self.process_reply_link_key(cmd.get_bd_addr(), true);
- }
- SecurityCommandChild::LinkKeyRequestNegativeReply(cmd) => {
- self.process_reply_link_key(cmd.get_bd_addr(), false);
- }
-
- // CommandChild::SecurityCommand(cmd).specialize()
- _ => {}
- },
-
- CommandChild::LeSecurityCommand(cmd) => match cmd.specialize() {
- LeSecurityCommandChild::LeStartEncryption(cmd) => {
- self.pending_le_encrypt.insert(cmd.get_connection_handle());
- }
-
- // CommandChild::LeSecurityCommand(cmd).specialize()
- _ => {}
- },
-
+ // Have an arm for Disconnect since sometimes we don't receive disconnect
+ // event when powering off. However, no need to actually match the reason
+ // since we just clean the handle in both cases.
+ CommandChild::Disconnect(cmd) => {
+ self.process_handle_auth(
+ ErrorCode::Success,
+ cmd.get_connection_handle(),
+ &packet,
+ );
+ self.handles.remove(&cmd.get_connection_handle());
+ }
+ CommandChild::LinkKeyRequestReply(cmd) => {
+ self.process_reply_link_key(cmd.get_bd_addr(), true);
+ }
+ CommandChild::LinkKeyRequestNegativeReply(cmd) => {
+ self.process_reply_link_key(cmd.get_bd_addr(), false);
+ }
+ CommandChild::LeStartEncryption(cmd) => {
+ self.pending_le_encrypt.insert(cmd.get_connection_handle());
+ }
CommandChild::Reset(_) => {
self.process_reset();
}
diff --git a/floss/hcidoc/src/groups/informational.rs b/floss/hcidoc/src/groups/informational.rs
index e224f481b2..dbaa6c8ae3 100644
--- a/floss/hcidoc/src/groups/informational.rs
+++ b/floss/hcidoc/src/groups/informational.rs
@@ -10,8 +10,8 @@ use std::io::Write;
use crate::engine::{Rule, RuleGroup, Signal};
use crate::parser::{get_acl_content, AclContent, Packet, PacketChild};
use hcidoc_packets::hci::{
- AclCommandChild, Address, CommandChild, ConnectionManagementCommandChild, DisconnectReason,
- ErrorCode, EventChild, GapData, GapDataType, LeMetaEventChild,
+ Address, CommandChild, DisconnectReason, ErrorCode, EventChild, GapData, GapDataType,
+ LeMetaEventChild,
};
use hcidoc_packets::l2cap::{ConnectionResponseResult, ControlChild};
@@ -23,18 +23,27 @@ type Cid = u16;
const INVALID_TS: NaiveDateTime = NaiveDateTime::MAX;
-fn print_start_end_timestamps(start: NaiveDateTime, end: NaiveDateTime) -> String {
- fn print_time(ts: NaiveDateTime) -> String {
+fn print_timestamps_and_initiator(
+ start: NaiveDateTime,
+ start_initiator: InitiatorType,
+ end: NaiveDateTime,
+ end_initiator: InitiatorType,
+) -> String {
+ fn print_time_initiator(ts: NaiveDateTime, initiator: InitiatorType) -> String {
if ts == INVALID_TS {
return "N/A".to_owned();
}
- return format!("{}", ts.time());
+ return format!("{} ({})", ts.time(), initiator);
}
if start == end && start != INVALID_TS {
- return format!("{} - Failed", start.time());
+ return format!("{} ({}) - Failed", start.time(), start_initiator);
}
- return format!("{} to {}", print_time(start), print_time(end));
+ return format!(
+ "{} to {}",
+ print_time_initiator(start, start_initiator),
+ print_time_initiator(end, end_initiator)
+ );
}
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
@@ -74,7 +83,7 @@ impl AddressType {
}
}
-#[derive(PartialEq)]
+#[derive(Clone, Copy, PartialEq)]
enum InitiatorType {
Unknown,
Host,
@@ -84,9 +93,9 @@ enum InitiatorType {
impl fmt::Display for InitiatorType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let str = match self {
- InitiatorType::Unknown => "Unknown initiator",
- InitiatorType::Host => "Host initiated",
- InitiatorType::Peer => "Peer initiated",
+ InitiatorType::Unknown => "by ??",
+ InitiatorType::Host => "by host",
+ InitiatorType::Peer => "by peer",
};
write!(f, "{}", str)
}
@@ -100,8 +109,8 @@ enum AclState {
Connected,
}
-impl Into<InitiatorType> for AclState {
- fn into(self) -> InitiatorType {
+impl AclState {
+ fn get_connection_initiator(&self) -> InitiatorType {
match self {
AclState::Initiating => InitiatorType::Host,
AclState::Accepting => InitiatorType::Peer,
@@ -145,15 +154,20 @@ impl DeviceInformation {
fn report_connection_start(&mut self, handle: ConnectionHandle, ts: NaiveDateTime) {
let mut acl = AclInformation::new(handle);
- let initiator = self.acl_state.into();
+ let initiator = self.acl_state.get_connection_initiator();
acl.report_start(initiator, ts);
self.acls.push(acl);
self.acl_state = AclState::Connected;
}
- fn report_connection_end(&mut self, handle: ConnectionHandle, ts: NaiveDateTime) {
+ fn report_connection_end(
+ &mut self,
+ handle: ConnectionHandle,
+ initiator: InitiatorType,
+ ts: NaiveDateTime,
+ ) {
let acl = self.get_or_allocate_connection(&handle);
- acl.report_end(ts);
+ acl.report_end(initiator, ts);
self.acl_state = AclState::None;
}
@@ -195,7 +209,8 @@ struct AclInformation {
start_time: NaiveDateTime,
end_time: NaiveDateTime,
handle: ConnectionHandle,
- initiator: InitiatorType,
+ start_initiator: InitiatorType,
+ end_initiator: InitiatorType,
active_profiles: HashMap<ProfileId, ProfileInformation>,
inactive_profiles: Vec<ProfileInformation>,
host_cids: HashMap<Cid, CidState>,
@@ -208,7 +223,8 @@ impl AclInformation {
start_time: INVALID_TS,
end_time: INVALID_TS,
handle: handle,
- initiator: InitiatorType::Unknown,
+ start_initiator: InitiatorType::Unknown,
+ end_initiator: InitiatorType::Unknown,
active_profiles: HashMap::new(),
inactive_profiles: vec![],
host_cids: HashMap::new(),
@@ -217,16 +233,17 @@ impl AclInformation {
}
fn report_start(&mut self, initiator: InitiatorType, ts: NaiveDateTime) {
- self.initiator = initiator;
+ self.start_initiator = initiator;
self.start_time = ts;
}
- fn report_end(&mut self, ts: NaiveDateTime) {
+ fn report_end(&mut self, initiator: InitiatorType, ts: NaiveDateTime) {
// disconnect the active profiles
for (_, mut profile) in self.active_profiles.drain() {
- profile.report_end(ts);
+ profile.report_end(initiator, ts);
self.inactive_profiles.push(profile);
}
+ self.end_initiator = initiator;
self.end_time = ts;
}
@@ -237,7 +254,7 @@ impl AclInformation {
initiator: InitiatorType,
ts: NaiveDateTime,
) {
- let mut profile = ProfileInformation::new(profile_type);
+ let mut profile = ProfileInformation::new(profile_type, profile_id);
profile.report_start(initiator, ts);
let old_profile = self.active_profiles.insert(profile_id, profile);
if let Some(profile) = old_profile {
@@ -249,13 +266,14 @@ impl AclInformation {
&mut self,
profile_type: ProfileType,
profile_id: ProfileId,
+ initiator: InitiatorType,
ts: NaiveDateTime,
) {
let mut profile = self
.active_profiles
.remove(&profile_id)
- .unwrap_or(ProfileInformation::new(profile_type));
- profile.report_end(ts);
+ .unwrap_or(ProfileInformation::new(profile_type, profile_id));
+ profile.report_end(initiator, ts);
self.inactive_profiles.push(profile);
}
@@ -278,11 +296,12 @@ impl AclInformation {
fn report_l2cap_conn_rsp(
&mut self,
status: ConnectionResponseResult,
- host_cid: Cid,
- peer_cid: Cid,
+ cid_info: CidInformation,
initiator: InitiatorType,
ts: NaiveDateTime,
) {
+ let host_cid = cid_info.host_cid;
+ let peer_cid = cid_info.peer_cid;
let cid_state_option = match initiator {
InitiatorType::Host => self.host_cids.get(&host_cid),
InitiatorType::Peer => self.peer_cids.get(&peer_cid),
@@ -299,7 +318,7 @@ impl AclInformation {
if let Some(psm) = psm_option {
let profile_option = ProfileType::from_psm(psm);
- let profile_id = ProfileId::L2capCid(host_cid);
+ let profile_id = ProfileId::L2capCid(cid_info);
if status == ConnectionResponseResult::Success {
self.host_cids.insert(host_cid, CidState::Connected(peer_cid, psm));
self.peer_cids.insert(peer_cid, CidState::Connected(host_cid, psm));
@@ -310,7 +329,7 @@ impl AclInformation {
// On failure, report start and end on the same time.
if let Some(profile) = profile_option {
self.report_profile_start(profile, profile_id, initiator, ts);
- self.report_profile_end(profile, profile_id, ts);
+ self.report_profile_end(profile, profile_id, initiator, ts);
}
}
} // TODO: debug on the else case.
@@ -319,11 +338,11 @@ impl AclInformation {
// L2cap disconnected so report profile connection closed if we were tracking it.
fn report_l2cap_disconn_rsp(
&mut self,
- host_cid: Cid,
- peer_cid: Cid,
- _initiator: InitiatorType,
+ cid_info: CidInformation,
+ initiator: InitiatorType,
ts: NaiveDateTime,
) {
+ let host_cid = cid_info.host_cid;
let host_cid_state_option = self.host_cids.remove(&host_cid);
let host_psm = match host_cid_state_option {
Some(cid_state) => match cid_state {
@@ -334,6 +353,7 @@ impl AclInformation {
None => None,
};
+ let peer_cid = cid_info.peer_cid;
let peer_cid_state_option = self.peer_cids.remove(&peer_cid);
let peer_psm = match peer_cid_state_option {
Some(cid_state) => match cid_state {
@@ -357,8 +377,8 @@ impl AclInformation {
let profile_option = ProfileType::from_psm(psm);
if let Some(profile) = profile_option {
- let profile_id = ProfileId::L2capCid(host_cid);
- self.report_profile_end(profile, profile_id, ts)
+ let profile_id = ProfileId::L2capCid(cid_info);
+ self.report_profile_end(profile, profile_id, initiator, ts)
}
}
}
@@ -367,10 +387,14 @@ impl fmt::Display for AclInformation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let _ = writeln!(
f,
- " Handle: {handle}, {initiator}, {timestamp_info}",
+ " Handle: {handle}, {timestamp_initiator_info}",
handle = self.handle,
- initiator = self.initiator,
- timestamp_info = print_start_end_timestamps(self.start_time, self.end_time)
+ timestamp_initiator_info = print_timestamps_and_initiator(
+ self.start_time,
+ self.start_initiator,
+ self.end_time,
+ self.end_initiator
+ ),
);
for profile in self.inactive_profiles.iter() {
@@ -430,37 +454,61 @@ impl ProfileType {
}
}
+#[derive(Clone, Copy, Eq, Hash, PartialEq)]
+struct CidInformation {
+ host_cid: Cid,
+ peer_cid: Cid,
+}
+
// Use to distinguish between the same profiles within one ACL connection.
// Later we can add RFCOMM's DLCI, for example.
+// This is used as the key of the map of active profiles in AclInformation.
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
enum ProfileId {
OnePerConnection(ProfileType),
- L2capCid(Cid),
+ L2capCid(CidInformation),
+}
+
+impl fmt::Display for ProfileId {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let str = match self {
+ ProfileId::OnePerConnection(_) => "".to_string(),
+ ProfileId::L2capCid(cid_info) => {
+ format!("(CID: host={}, peer={})", cid_info.host_cid, cid_info.peer_cid)
+ }
+ };
+ write!(f, "{}", str)
+ }
}
struct ProfileInformation {
start_time: NaiveDateTime,
end_time: NaiveDateTime,
profile_type: ProfileType,
- initiator: InitiatorType,
+ start_initiator: InitiatorType,
+ end_initiator: InitiatorType,
+ profile_id: ProfileId,
}
impl ProfileInformation {
- pub fn new(profile_type: ProfileType) -> Self {
+ pub fn new(profile_type: ProfileType, profile_id: ProfileId) -> Self {
ProfileInformation {
start_time: INVALID_TS,
end_time: INVALID_TS,
profile_type: profile_type,
- initiator: InitiatorType::Unknown,
+ start_initiator: InitiatorType::Unknown,
+ end_initiator: InitiatorType::Unknown,
+ profile_id: profile_id,
}
}
fn report_start(&mut self, initiator: InitiatorType, ts: NaiveDateTime) {
- self.initiator = initiator;
+ self.start_initiator = initiator;
self.start_time = ts;
}
- fn report_end(&mut self, ts: NaiveDateTime) {
+ fn report_end(&mut self, initiator: InitiatorType, ts: NaiveDateTime) {
+ self.end_initiator = initiator;
self.end_time = ts;
}
}
@@ -469,10 +517,15 @@ impl fmt::Display for ProfileInformation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(
f,
- " {profile}, {initiator}, {timestamp_info}",
+ " {profile}, {timestamp_initiator_info} {profile_id}",
profile = self.profile_type,
- initiator = self.initiator,
- timestamp_info = print_start_end_timestamps(self.start_time, self.end_time)
+ timestamp_initiator_info = print_timestamps_and_initiator(
+ self.start_time,
+ self.start_initiator,
+ self.end_time,
+ self.end_initiator
+ ),
+ profile_id = self.profile_id,
)
}
}
@@ -484,9 +537,13 @@ struct InformationalRule {
sco_handles: HashMap<ConnectionHandle, ConnectionHandle>,
/// unknownConnections store connections which is initiated before btsnoop starts.
unknown_connections: HashMap<ConnectionHandle, AclInformation>,
- /// When powering off, the controller might or might not reply disconnection request. Therefore
- /// make this a special case.
- pending_disconnect_due_to_host_power_off: HashSet<ConnectionHandle>,
+ /// Store the pending disconnection so we can retrieve who initiates it upon report.
+ /// This needs its own map instead of reusing the AclState, because that requires us to have the
+ /// address of the peer device, but on disconnection we are given only the handle - the address
+ /// might be unknown, or clash in case of a SCO connection.
+ /// Also, when powering off, the controller might or might not reply the disconnection request.
+ /// Therefore also store this information so we can correctly handle both scenario.
+ pending_disconnections: HashMap<ConnectionHandle, bool>, // is powering off?
}
impl InformationalRule {
@@ -496,7 +553,7 @@ impl InformationalRule {
handles: HashMap::new(),
sco_handles: HashMap::new(),
unknown_connections: HashMap::new(),
- pending_disconnect_due_to_host_power_off: HashSet::new(),
+ pending_disconnections: HashMap::new(),
}
}
@@ -552,7 +609,7 @@ impl InformationalRule {
let device = self.get_or_allocate_device(address);
device.report_connection_start(handle, ts);
self.handles.insert(handle, *address);
- self.pending_disconnect_due_to_host_power_off.remove(&handle);
+ self.pending_disconnections.remove(&handle);
}
fn report_sco_connection_start(
@@ -589,13 +646,21 @@ impl InformationalRule {
}
fn report_connection_end(&mut self, handle: ConnectionHandle, ts: NaiveDateTime) {
+ let initiator = match self.pending_disconnections.contains_key(&handle) {
+ true => InitiatorType::Host,
+ false => InitiatorType::Peer,
+ };
+
// 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);
+ // in case of HFP failure, the initiator here would be set to peer, which is incorrect,
+ // but when printing we detect by the timestamp that it was a failure anyway.
conn.report_profile_end(
ProfileType::Hfp,
ProfileId::OnePerConnection(ProfileType::Hfp),
+ initiator,
ts,
);
return;
@@ -604,8 +669,8 @@ impl InformationalRule {
// 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);
+ let device: &mut DeviceInformation = self.devices.get_mut(address).unwrap();
+ device.report_connection_end(handle, initiator, ts);
self.handles.remove(&handle);
// remove the associated SCO handle, if any
@@ -613,7 +678,7 @@ impl InformationalRule {
} else {
// Unknown device.
let conn = self.get_or_allocate_unknown_connection(&handle);
- conn.report_end(ts);
+ conn.report_end(initiator, ts);
}
}
@@ -624,7 +689,7 @@ impl InformationalRule {
self.report_connection_end(handle, ts);
}
self.sco_handles.clear();
- self.pending_disconnect_due_to_host_power_off.clear();
+ self.pending_disconnections.clear();
}
fn process_gap_data(&mut self, address: &Address, data: &GapData) {
@@ -641,18 +706,20 @@ impl InformationalRule {
fn process_raw_gap_data(&mut self, address: &Address, data: &[u8]) {
let mut offset = 0;
while offset < data.len() {
- let chunk_size = usize::from(data[offset]);
- let chunk_end = offset + chunk_size + 1;
-
- // Prevent out-of-bounds index
- if chunk_end > data.len() {
- return;
+ match GapData::parse(&data[offset..]) {
+ Ok(gap_data) => {
+ self.process_gap_data(&address, &gap_data);
+ // advance data len + 2 (size = 1, type = 1)
+ offset += gap_data.data.len() + 2;
+ }
+ Err(err) => {
+ eprintln!("[{}] GAP data is not parsed correctly: {}", address, err);
+ break;
+ }
}
- match GapData::parse(&data[offset..chunk_end]) {
- Ok(gap_data) => self.process_gap_data(&address, &gap_data),
- Err(_err) => {}
+ if offset >= data.len() {
+ break;
}
- offset = chunk_end;
}
}
@@ -681,7 +748,8 @@ impl InformationalRule {
return;
}
let conn = self.get_or_allocate_connection(&handle);
- conn.report_l2cap_conn_rsp(status, host_cid, peer_cid, initiator, ts);
+ let cid_info = CidInformation { host_cid, peer_cid };
+ conn.report_l2cap_conn_rsp(status, cid_info, initiator, ts);
}
fn report_l2cap_disconn_rsp(
@@ -693,7 +761,8 @@ impl InformationalRule {
ts: NaiveDateTime,
) {
let conn = self.get_or_allocate_connection(&handle);
- conn.report_l2cap_disconn_rsp(host_cid, peer_cid, initiator, ts);
+ let cid_info = CidInformation { host_cid, peer_cid };
+ conn.report_l2cap_disconn_rsp(cid_info, initiator, ts);
}
}
@@ -729,18 +798,18 @@ impl Rule for InformationalRule {
EventChild::DisconnectionComplete(ev) => {
// If disconnected because host is powering off, the event has been processed.
// We can't just query the reason here because it's different across vendors.
- if !self
- .pending_disconnect_due_to_host_power_off
- .remove(&ev.get_connection_handle())
- {
- self.report_connection_end(ev.get_connection_handle(), packet.ts);
+ let handle = ev.get_connection_handle();
+ if !self.pending_disconnections.get(&handle).unwrap_or(&false) {
+ self.report_connection_end(handle, packet.ts);
}
+ self.pending_disconnections.remove(&handle);
}
EventChild::ExtendedInquiryResult(ev) => {
- for data in ev.get_extended_inquiry_response() {
- self.process_gap_data(&ev.get_address(), data);
- }
+ self.process_raw_gap_data(
+ &ev.get_address(),
+ ev.get_extended_inquiry_response(),
+ );
self.report_address_type(&ev.get_address(), AddressType::BREDR);
}
@@ -785,16 +854,14 @@ impl Rule for InformationalRule {
self.report_address_type(&ev.get_peer_address(), AddressType::LE);
}
- // Use the Raw version because somehow LeAdvertisingReport doesn't work
- LeMetaEventChild::LeAdvertisingReportRaw(ev) => {
+ LeMetaEventChild::LeAdvertisingReport(ev) => {
for resp in ev.get_responses() {
self.process_raw_gap_data(&resp.address, &resp.advertising_data);
self.report_address_type(&resp.address, AddressType::LE);
}
}
- // Use the Raw version because somehow LeExtendedAdvertisingReport doesn't work
- LeMetaEventChild::LeExtendedAdvertisingReportRaw(ev) => {
+ LeMetaEventChild::LeExtendedAdvertisingReport(ev) => {
for resp in ev.get_responses() {
self.process_raw_gap_data(&resp.address, &resp.advertising_data);
self.report_address_type(&resp.address, AddressType::LE);
@@ -813,37 +880,24 @@ impl Rule for InformationalRule {
CommandChild::Reset(_cmd) => {
self.report_reset(packet.ts);
}
-
- CommandChild::AclCommand(cmd) => match cmd.specialize() {
- AclCommandChild::ConnectionManagementCommand(cmd) => match cmd.specialize() {
- ConnectionManagementCommandChild::CreateConnection(cmd) => {
- self.report_acl_state(&cmd.get_bd_addr(), AclState::Initiating);
- self.report_address_type(&cmd.get_bd_addr(), AddressType::BREDR);
- }
-
- ConnectionManagementCommandChild::AcceptConnectionRequest(cmd) => {
- self.report_acl_state(&cmd.get_bd_addr(), AclState::Accepting);
- self.report_address_type(&cmd.get_bd_addr(), AddressType::BREDR);
- }
-
- // AclCommandChild::ConnectionManagementCommand(cmd).specialize()
- _ => {}
- },
-
- AclCommandChild::Disconnect(cmd) => {
- // If reason is power off, the host might not wait for connection complete event
- if cmd.get_reason()
- == DisconnectReason::RemoteDeviceTerminatedConnectionPowerOff
- {
- self.pending_disconnect_due_to_host_power_off
- .insert(cmd.get_connection_handle());
- self.report_connection_end(cmd.get_connection_handle(), packet.ts);
- }
+ CommandChild::CreateConnection(cmd) => {
+ self.report_acl_state(&cmd.get_bd_addr(), AclState::Initiating);
+ self.report_address_type(&cmd.get_bd_addr(), AddressType::BREDR);
+ }
+ CommandChild::AcceptConnectionRequest(cmd) => {
+ self.report_acl_state(&cmd.get_bd_addr(), AclState::Accepting);
+ self.report_address_type(&cmd.get_bd_addr(), AddressType::BREDR);
+ }
+ CommandChild::Disconnect(cmd) => {
+ // If reason is power off, the host might not wait for connection complete event
+ let is_power_off = cmd.get_reason()
+ == DisconnectReason::RemoteDeviceTerminatedConnectionPowerOff;
+ let handle = cmd.get_connection_handle();
+ self.pending_disconnections.insert(handle, is_power_off);
+ if is_power_off {
+ self.report_connection_end(handle, packet.ts);
}
-
- // CommandChild::AclCommand(cmd).specialize()
- _ => {}
- },
+ }
// PacketChild::HciCommand(cmd).specialize()
_ => {}
diff --git a/framework/Android.bp b/framework/Android.bp
index 9fa8d9a160..2eca8df89b 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -10,6 +10,7 @@ filegroup {
"java/**/*.java",
],
path: "java",
+ visibility: ["//packages/modules/Bluetooth/framework/tests/unit"],
}
// defaults shared between `framework-bluetooth` & `framework-bluetooth-pre-jarjar`
@@ -49,6 +50,7 @@ java_library {
sdk_version: "module_current",
libs: ["framework-annotations-lib"],
installable: false,
+ visibility: ["//packages/modules/Bluetooth:__subpackages__"],
}
// post-jarjar version of framework-bluetooth
@@ -85,12 +87,14 @@ java_sdk_library {
permitted_packages: [
"android.bluetooth",
- "com.android.bluetooth.flags",
"com.android.bluetooth.jarjar",
],
plugins: [
"error_prone_android_framework",
],
+ aconfig_declarations: [
+ "bluetooth_aconfig_flags",
+ ],
lint: {
error_checks: [
"Autofill",
@@ -146,7 +150,7 @@ java_defaults {
// if sdk_version="" this gets automatically included, but here we need to add manually.
"framework-res",
],
- defaults_visibility: ["//visibility:public"],
+ defaults_visibility: ["//packages/modules/Bluetooth:__subpackages__"],
}
filegroup {
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index f7e87588ba..7aa89155b1 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -191,7 +191,7 @@ package android.bluetooth {
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBondOutOfBand(int, @Nullable android.bluetooth.OobData, @Nullable android.bluetooth.OobData);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int disconnect();
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}, conditional=true) public boolean fetchUuidsWithSdp(int);
- method @FlaggedApi("com.android.bluetooth.flags.metadata_api_inactive_audio_device_upon_connection") @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getActiveAudioDevicePolicy();
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getActiveAudioDevicePolicy();
method @NonNull public String getAnonymizedAddress();
method @IntRange(from=0xffffff9c, to=100) @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getBatteryLevel();
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionHandle(int);
@@ -210,7 +210,7 @@ package android.bluetooth {
method public void prepareToEnterProcess(@NonNull android.content.AttributionSource);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean removeBond();
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int requestAudioPolicyAsSink(@NonNull android.bluetooth.BluetoothSinkAudioPolicy);
- method @FlaggedApi("com.android.bluetooth.flags.metadata_api_inactive_audio_device_upon_connection") @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int setActiveAudioDevicePolicy(int);
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int setActiveAudioDevicePolicy(int);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setLowLatencyAudioAllowed(boolean);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setMessageAccessPermission(int);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setMetadata(int, @NonNull byte[]);
@@ -229,9 +229,9 @@ package android.bluetooth {
field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_PAIRING_CANCEL = "android.bluetooth.device.action.PAIRING_CANCEL";
field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_SILENCE_MODE_CHANGED = "android.bluetooth.device.action.SILENCE_MODE_CHANGED";
field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_SWITCH_BUFFER_SIZE = "android.bluetooth.device.action.SWITCH_BUFFER_SIZE";
- field @FlaggedApi("com.android.bluetooth.flags.metadata_api_inactive_audio_device_upon_connection") public static final int ACTIVE_AUDIO_DEVICE_POLICY_ALL_PROFILES_ACTIVE_UPON_CONNECTION = 1; // 0x1
- field @FlaggedApi("com.android.bluetooth.flags.metadata_api_inactive_audio_device_upon_connection") public static final int ACTIVE_AUDIO_DEVICE_POLICY_ALL_PROFILES_INACTIVE_UPON_CONNECTION = 2; // 0x2
- field @FlaggedApi("com.android.bluetooth.flags.metadata_api_inactive_audio_device_upon_connection") public static final int ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT = 0; // 0x0
+ field public static final int ACTIVE_AUDIO_DEVICE_POLICY_ALL_PROFILES_ACTIVE_UPON_CONNECTION = 1; // 0x1
+ field public static final int ACTIVE_AUDIO_DEVICE_POLICY_ALL_PROFILES_INACTIVE_UPON_CONNECTION = 2; // 0x2
+ field public static final int ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT = 0; // 0x0
field public static final int BATTERY_LEVEL_BLUETOOTH_OFF = -100; // 0xffffff9c
field public static final int BATTERY_LEVEL_UNKNOWN = -1; // 0xffffffff
field public static final int CONNECTION_ACCESS_NO = 2; // 0x2
@@ -479,11 +479,11 @@ package android.bluetooth {
field public static final int AUDIO_LOCATION_FRONT_RIGHT = 2; // 0x2
field public static final int AUDIO_LOCATION_FRONT_RIGHT_OF_CENTER = 128; // 0x80
field public static final int AUDIO_LOCATION_FRONT_RIGHT_WIDE = 33554432; // 0x2000000
- field @Deprecated @FlaggedApi("com.android.bluetooth.flags.leaudio_mono_location_errata") public static final int AUDIO_LOCATION_INVALID = 0; // 0x0
+ field @Deprecated @FlaggedApi("com.android.bluetooth.flags.leaudio_mono_location_errata_api") public static final int AUDIO_LOCATION_INVALID = 0; // 0x0
field public static final int AUDIO_LOCATION_LEFT_SURROUND = 67108864; // 0x4000000
field public static final int AUDIO_LOCATION_LOW_FREQ_EFFECTS_ONE = 8; // 0x8
field public static final int AUDIO_LOCATION_LOW_FREQ_EFFECTS_TWO = 512; // 0x200
- field @FlaggedApi("com.android.bluetooth.flags.leaudio_mono_location_errata") public static final int AUDIO_LOCATION_MONO = 0; // 0x0
+ field @FlaggedApi("com.android.bluetooth.flags.leaudio_mono_location_errata_api") public static final int AUDIO_LOCATION_MONO = 0; // 0x0
field public static final int AUDIO_LOCATION_RIGHT_SURROUND = 134217728; // 0x8000000
field public static final int AUDIO_LOCATION_SIDE_LEFT = 1024; // 0x400
field public static final int AUDIO_LOCATION_SIDE_RIGHT = 2048; // 0x800
@@ -496,7 +496,7 @@ package android.bluetooth {
field public static final int AUDIO_LOCATION_TOP_FRONT_RIGHT = 8192; // 0x2000
field public static final int AUDIO_LOCATION_TOP_SIDE_LEFT = 262144; // 0x40000
field public static final int AUDIO_LOCATION_TOP_SIDE_RIGHT = 524288; // 0x80000
- field @FlaggedApi("com.android.bluetooth.flags.leaudio_mono_location_errata") public static final int AUDIO_LOCATION_UNKNOWN = -2147483648; // 0x80000000
+ field @FlaggedApi("com.android.bluetooth.flags.leaudio_mono_location_errata_api") public static final int AUDIO_LOCATION_UNKNOWN = -2147483648; // 0x80000000
field public static final String EXTRA_LE_AUDIO_GROUP_ID = "android.bluetooth.extra.LE_AUDIO_GROUP_ID";
field public static final int GROUP_STREAM_STATUS_IDLE = 0; // 0x0
field public static final int GROUP_STREAM_STATUS_STREAMING = 1; // 0x1
@@ -1166,8 +1166,8 @@ package android.bluetooth {
method @NonNull public byte[] getDeviceAddressWithType();
method @Nullable public byte[] getDeviceName();
method @Nullable public byte[] getLeAppearance();
- method @NonNull public int getLeDeviceRole();
- method @NonNull public int getLeFlags();
+ method public int getLeDeviceRole();
+ method public int getLeFlags();
method @Nullable public byte[] getLeTemporaryKey();
method @NonNull public byte[] getRandomizerHash();
method public void writeToParcel(@NonNull android.os.Parcel, int);
@@ -1382,9 +1382,9 @@ package android.bluetooth.le {
public static interface DistanceMeasurementSession.Callback {
method public void onResult(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.le.DistanceMeasurementResult);
- method public void onStartFail(@NonNull int);
+ method public void onStartFail(int);
method public void onStarted(@NonNull android.bluetooth.le.DistanceMeasurementSession);
- method public void onStopped(@NonNull android.bluetooth.le.DistanceMeasurementSession, @NonNull int);
+ method public void onStopped(@NonNull android.bluetooth.le.DistanceMeasurementSession, int);
}
@Deprecated public final class ResultStorageDescriptor implements android.os.Parcelable {
diff --git a/framework/jarjar-rules.txt b/framework/jarjar-rules.txt
index 172bdd439e..cff2b1aa31 100644
--- a/framework/jarjar-rules.txt
+++ b/framework/jarjar-rules.txt
@@ -10,3 +10,4 @@ rule android.hardware.radio.V1_0.** com.android.bluetooth.jarjar.@0
rule com.google.android.mms.** com.android.bluetooth.jarjar.@0
rule com.android.internal.util.** com.android.bluetooth.jarjar.@0
rule com.android.modules.expresslog.** com.android.bluetooth.jarjar.@0
+rule com.android.bluetooth.flags.** com.android.bluetooth.jarjar.@0
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java
index ce8b74f74f..f345bb5502 100644
--- a/framework/java/android/bluetooth/BluetoothAdapter.java
+++ b/framework/java/android/bluetooth/BluetoothAdapter.java
@@ -1484,21 +1484,36 @@ public final class BluetoothAdapter {
throw e.rethrowAsRuntimeException();
}
}
+ @RequiresNoPermission
+ @Override
+ public boolean shouldBypassCache(IBluetooth serviceQuery) {
+ return false;
+ }
};
- private static final IpcDataCache.QueryHandler<IBluetoothManager, Integer>
- sBluetoothGetSystemStateQuery =
- new IpcDataCache.QueryHandler<>() {
- @RequiresNoPermission
- @Override
- public @InternalAdapterState Integer apply(IBluetoothManager serviceQuery) {
- try {
- return serviceQuery.getState();
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
- }
- }
- };
+ private static final IpcDataCache.QueryHandler<Void, Integer> sBluetoothGetSystemStateQuery =
+ new IpcDataCache.QueryHandler<>() {
+ @RequiresNoPermission
+ @Override
+ public @InternalAdapterState Integer apply(Void query) {
+ try {
+ IBluetoothManager service =
+ IBluetoothManager.Stub.asInterface(
+ BluetoothFrameworkInitializer.getBluetoothServiceManager()
+ .getBluetoothManagerServiceRegisterer()
+ .get());
+ return service.getState();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ @RequiresNoPermission
+ @Override
+ public boolean shouldBypassCache(Void query) {
+ return false;
+ }
+ };
private static final String GET_STATE_API = "BluetoothAdapter_getState";
@@ -1508,9 +1523,9 @@ public final class BluetoothAdapter {
private static final IpcDataCache<IBluetooth, Integer> sBluetoothGetStateCache =
new BluetoothCache<>(GET_STATE_API, sBluetoothGetStateQuery);
- private static final IpcDataCache<IBluetoothManager, Integer> sBluetoothGetSystemStateCache =
+ private static final IpcDataCache<Void, Integer> sBluetoothGetSystemStateCache =
new IpcDataCache<>(
- 8,
+ 1,
IBluetoothManager.IPC_CACHE_MODULE_SYSTEM,
GET_SYSTEM_STATE_API,
GET_SYSTEM_STATE_API,
@@ -1536,14 +1551,7 @@ public final class BluetoothAdapter {
/** Fetch the current bluetooth state. If the service is down, return OFF. */
private @InternalAdapterState int getStateInternal() {
if (Flags.getStateFromSystemServer()) {
- try {
- return sBluetoothGetSystemStateCache.query(mManagerService);
- } catch (RuntimeException runtime) {
- if (runtime.getCause() instanceof RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- throw runtime;
- }
+ return sBluetoothGetSystemStateCache.query(null);
}
mServiceLock.readLock().lock();
try {
@@ -2405,6 +2413,11 @@ public final class BluetoothAdapter {
throw e.rethrowAsRuntimeException();
}
}
+ @RequiresNoPermission
+ @Override
+ public boolean shouldBypassCache(IBluetooth serviceQuery) {
+ return false;
+ }
};
private static final String FILTERING_API = "BluetoothAdapter_isOffloadedFilteringSupported";
@@ -2948,6 +2961,11 @@ public final class BluetoothAdapter {
throw e.rethrowAsRuntimeException();
}
}
+ @RequiresNoPermission
+ @Override
+ public boolean shouldBypassCache(IBluetooth serviceQuery) {
+ return false;
+ }
};
private static final String GET_CONNECTION_API = "BluetoothAdapter_getConnectionState";
@@ -3017,6 +3035,12 @@ public final class BluetoothAdapter {
throw e.rethrowAsRuntimeException();
}
}
+ @RequiresNoPermission
+ @Override
+ public boolean shouldBypassCache(
+ Pair<IBluetooth, Pair<AttributionSource, Integer>> pairQuery) {
+ return false;
+ }
};
private static final String PROFILE_API = "BluetoothAdapter_getProfileConnectionState";
diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java
index 4da94af0d8..9bd547d33a 100644
--- a/framework/java/android/bluetooth/BluetoothDevice.java
+++ b/framework/java/android/bluetooth/BluetoothDevice.java
@@ -1361,7 +1361,6 @@ public final class BluetoothDevice implements Parcelable, Attributable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_METADATA_API_INACTIVE_AUDIO_DEVICE_UPON_CONNECTION)
@SystemApi
public static final int ACTIVE_AUDIO_DEVICE_POLICY_DEFAULT = 0;
@@ -1372,7 +1371,6 @@ public final class BluetoothDevice implements Parcelable, Attributable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_METADATA_API_INACTIVE_AUDIO_DEVICE_UPON_CONNECTION)
@SystemApi
public static final int ACTIVE_AUDIO_DEVICE_POLICY_ALL_PROFILES_ACTIVE_UPON_CONNECTION = 1;
@@ -1383,7 +1381,6 @@ public final class BluetoothDevice implements Parcelable, Attributable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_METADATA_API_INACTIVE_AUDIO_DEVICE_UPON_CONNECTION)
@SystemApi
public static final int ACTIVE_AUDIO_DEVICE_POLICY_ALL_PROFILES_INACTIVE_UPON_CONNECTION = 2;
@@ -3460,7 +3457,6 @@ public final class BluetoothDevice implements Parcelable, Attributable {
* @throws IllegalArgumentException if this BluetoothDevice object has an invalid address
* @hide
*/
- @FlaggedApi(Flags.FLAG_METADATA_API_INACTIVE_AUDIO_DEVICE_UPON_CONNECTION)
@SystemApi
@RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
@@ -3492,7 +3488,6 @@ public final class BluetoothDevice implements Parcelable, Attributable {
* @return active audio device policy of the device
* @hide
*/
- @FlaggedApi(Flags.FLAG_METADATA_API_INACTIVE_AUDIO_DEVICE_UPON_CONNECTION)
@SystemApi
@RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
diff --git a/framework/java/android/bluetooth/BluetoothLeAudio.java b/framework/java/android/bluetooth/BluetoothLeAudio.java
index c11efe1683..6bc4a73de9 100644
--- a/framework/java/android/bluetooth/BluetoothLeAudio.java
+++ b/framework/java/android/bluetooth/BluetoothLeAudio.java
@@ -367,7 +367,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
* with a meaning MONO.
* @hide
*/
- @FlaggedApi(Flags.FLAG_LEAUDIO_MONO_LOCATION_ERRATA)
+ @FlaggedApi(Flags.FLAG_LEAUDIO_MONO_LOCATION_ERRATA_API)
@Deprecated
@SystemApi
public static final int AUDIO_LOCATION_INVALID = 0;
@@ -377,7 +377,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_LEAUDIO_MONO_LOCATION_ERRATA)
+ @FlaggedApi(Flags.FLAG_LEAUDIO_MONO_LOCATION_ERRATA_API)
@SystemApi
public static final int AUDIO_LOCATION_MONO = 0;
@@ -386,7 +386,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
*
* @hide
*/
- @FlaggedApi(Flags.FLAG_LEAUDIO_MONO_LOCATION_ERRATA)
+ @FlaggedApi(Flags.FLAG_LEAUDIO_MONO_LOCATION_ERRATA_API)
@SystemApi
public static final int AUDIO_LOCATION_UNKNOWN = 0x01 << 31;
@@ -1186,6 +1186,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
@SystemApi
@RequiresBluetoothConnectPermission
@RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED})
+ @SuppressWarnings("FlaggedApi") // Due to deprecated AUDIO_LOCATION_INVALID
public @AudioLocation int getAudioLocation(@NonNull BluetoothDevice device) {
if (VDBG) log("getAudioLocation()");
final IBluetoothLeAudio service = getService();
@@ -1200,7 +1201,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
}
}
- if (Flags.leaudioMonoLocationErrata()
+ if (Flags.leaudioMonoLocationErrataApi()
&& CompatChanges.isChangeEnabled(LEAUDIO_MONO_LOCATION_ERRATA)) {
return AUDIO_LOCATION_UNKNOWN;
}
diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java
index b802943b49..28b4e779ee 100644
--- a/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java
+++ b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java
@@ -316,6 +316,8 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile, Au
* Callback invoked when a new Broadcast Source is found together with the {@link
* BluetoothLeBroadcastMetadata}.
*
+ * <p>Broadcast is found when it is available for user to synchronize with it.
+ *
* @param source {@link BluetoothLeBroadcastMetadata} representing a Broadcast Source
* @hide
*/
@@ -443,8 +445,7 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile, Au
/**
* Callback invoked when the Broadcast Source is lost together with source broadcast id.
*
- * <p>This callback is to notify source lost due to periodic advertising sync lost. Callback
- * client can know that the source notified by {@link
+ * <p>Callback client can know that the source notified by {@link
* Callback#onSourceFound(BluetoothLeBroadcastMetadata)} before is not available any more
* after this callback.
*
diff --git a/framework/java/android/bluetooth/OobData.java b/framework/java/android/bluetooth/OobData.java
index a90516d616..e6c5f945d8 100644
--- a/framework/java/android/bluetooth/OobData.java
+++ b/framework/java/android/bluetooth/OobData.java
@@ -750,7 +750,6 @@ public final class OobData implements Parcelable {
* 55 of LMP Feature Mask Definitions. <b>0x05- 0x07 Reserved</b>
* @hide
*/
- @NonNull
@SystemApi
@LeFlag
public int getLeFlags() {
@@ -766,7 +765,6 @@ public final class OobData implements Parcelable {
* Preferred 0x04 - 0xFF Reserved
* @hide
*/
- @NonNull
@SystemApi
public @LeRole int getLeDeviceRole() {
return mLeDeviceRole;
@@ -849,7 +847,7 @@ public final class OobData implements Parcelable {
}
// For Parcelable
- public static final @android.annotation.NonNull Parcelable.Creator<OobData> CREATOR =
+ public static final @NonNull Parcelable.Creator<OobData> CREATOR =
new Parcelable.Creator<OobData>() {
public OobData createFromParcel(Parcel in) {
return new OobData(in);
diff --git a/framework/java/android/bluetooth/le/DistanceMeasurementSession.java b/framework/java/android/bluetooth/le/DistanceMeasurementSession.java
index d91fbade2c..a36887ba9b 100644
--- a/framework/java/android/bluetooth/le/DistanceMeasurementSession.java
+++ b/framework/java/android/bluetooth/le/DistanceMeasurementSession.java
@@ -177,7 +177,7 @@ public final class DistanceMeasurementSession {
* @hide
*/
@SystemApi
- void onStartFail(@NonNull @Reason int reason);
+ void onStartFail(@Reason int reason);
/**
* Invoked when a distance measurement session stopped.
@@ -186,7 +186,7 @@ public final class DistanceMeasurementSession {
* @hide
*/
@SystemApi
- void onStopped(@NonNull DistanceMeasurementSession session, @NonNull @Reason int reason);
+ void onStopped(@NonNull DistanceMeasurementSession session, @Reason int reason);
/**
* Invoked when get distance measurement result.
diff --git a/framework/tests/bumble/Android.bp b/framework/tests/bumble/Android.bp
index a97112171c..6c516acf11 100644
--- a/framework/tests/bumble/Android.bp
+++ b/framework/tests/bumble/Android.bp
@@ -54,7 +54,7 @@ java_test_host {
"tradefed",
],
- data: [
+ device_common_data: [
":BumbleBluetoothTestsApp",
"bumble_config.json",
],
@@ -80,9 +80,11 @@ java_test_host {
],
data: [
- ":BumbleBluetoothTestsApp",
"bumble_config.json",
],
+ device_common_data: [
+ ":BumbleBluetoothTestsApp",
+ ],
data_native_bins: [
"bumble_pandora_server",
],
diff --git a/framework/tests/metrics/host/Android.bp b/framework/tests/metrics/host/Android.bp
index f90e35a29d..4bb72818a1 100644
--- a/framework/tests/metrics/host/Android.bp
+++ b/framework/tests/metrics/host/Android.bp
@@ -16,7 +16,7 @@ java_test_host {
"tradefed",
],
- data: [
+ device_common_data: [
":BluetoothMetricsTestApp",
],
diff --git a/framework/tests/unit/Android.bp b/framework/tests/unit/Android.bp
index 96025ab7fb..39b3c29861 100644
--- a/framework/tests/unit/Android.bp
+++ b/framework/tests/unit/Android.bp
@@ -5,8 +5,7 @@ package {
android_test {
name: "FrameworkBluetoothTests",
- defaults: ["framework-bluetooth-tests-defaults"],
-
+ sdk_version: "module_current",
min_sdk_version: "Tiramisu",
target_sdk_version: "current",
@@ -19,11 +18,14 @@ android_test {
libs: [
"android.test.base.stubs",
"android.test.runner.stubs",
+ "framework-annotations-lib",
+ "framework-bluetooth.impl",
],
static_libs: [
"androidx.test.ext.truth",
"androidx.test.rules",
"flag-junit",
+ "framework-bluetooth-pre-jarjar",
"frameworks-base-testutils",
"junit",
"mockito-target",
diff --git a/framework/tests/unit/src/android/bluetooth/CallbackWrapperTest.java b/framework/tests/unit/src/android/bluetooth/CallbackWrapperTest.java
index a55fb033bc..0721ead366 100644
--- a/framework/tests/unit/src/android/bluetooth/CallbackWrapperTest.java
+++ b/framework/tests/unit/src/android/bluetooth/CallbackWrapperTest.java
@@ -22,8 +22,6 @@ import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import android.os.Handler;
-import android.os.HandlerExecutor;
import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
@@ -72,7 +70,7 @@ public class CallbackWrapperTest {
@Before
public void setUp() {
mLooper = new TestLooper();
- mExecutor = new HandlerExecutor(new Handler(mLooper.getLooper()));
+ mExecutor = mLooper.getNewExecutor();
mCallbackExecutorMap = new HashMap();
mCallbackWrapper =
new CallbackWrapper(mRegisterConsumer, mUnregisterConsumer, mCallbackExecutorMap);
diff --git a/framework/tests/unit/src/android/bluetooth/le/ScanRecordTest.java b/framework/tests/unit/src/android/bluetooth/le/ScanRecordTest.java
index ac228c6c9d..a690e510f5 100644
--- a/framework/tests/unit/src/android/bluetooth/le/ScanRecordTest.java
+++ b/framework/tests/unit/src/android/bluetooth/le/ScanRecordTest.java
@@ -22,7 +22,6 @@ import android.os.ParcelUuid;
import android.platform.test.flag.junit.SetFlagsRule;
import com.android.bluetooth.flags.Flags;
-import com.android.internal.util.HexDump;
import com.android.modules.utils.BytesMatcher;
import org.junit.Rule;
@@ -70,11 +69,10 @@ public class ScanRecordTest {
final List<String> found = new ArrayList<>();
final Predicate<byte[]> matcher =
(v) -> {
- found.add(HexDump.toHexString(v));
+ found.add(toHexString(v));
return false;
};
- ScanRecord.parseFromBytes(HexDump.hexStringToByteArray(RECORD_URL))
- .matchesAnyField(matcher);
+ ScanRecord.parseFromBytes(hexStringToByteArray(RECORD_URL)).matchesAnyField(matcher);
assertThat(found)
.isEqualTo(
@@ -112,11 +110,10 @@ public class ScanRecordTest {
final List<String> found = new ArrayList<>();
final Predicate<byte[]> matcher =
(v) -> {
- found.add(HexDump.toHexString(v));
+ found.add(toHexString(v));
return false;
};
- ScanRecord.parseFromBytes(HexDump.hexStringToByteArray(RECORD_IBEACON))
- .matchesAnyField(matcher);
+ ScanRecord.parseFromBytes(hexStringToByteArray(RECORD_IBEACON)).matchesAnyField(matcher);
assertThat(found)
.isEqualTo(
@@ -265,16 +262,49 @@ public class ScanRecordTest {
}
private static void assertMatchesAnyField(String record, BytesMatcher matcher) {
- assertThat(
- ScanRecord.parseFromBytes(HexDump.hexStringToByteArray(record))
- .matchesAnyField(matcher))
+ assertThat(ScanRecord.parseFromBytes(hexStringToByteArray(record)).matchesAnyField(matcher))
.isTrue();
}
private static void assertNotMatchesAnyField(String record, BytesMatcher matcher) {
- assertThat(
- ScanRecord.parseFromBytes(HexDump.hexStringToByteArray(record))
- .matchesAnyField(matcher))
+ assertThat(ScanRecord.parseFromBytes(hexStringToByteArray(record)).matchesAnyField(matcher))
.isFalse();
}
+
+ private static final char[] HEX_DIGITS = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+
+ private static String toHexString(byte[] array) {
+ char[] buf = new char[array.length * 2];
+
+ int bufIndex = 0;
+ for (int i = 0; i < array.length; i++) {
+ byte b = array[i];
+ buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F];
+ buf[bufIndex++] = HEX_DIGITS[b & 0x0F];
+ }
+
+ return new String(buf);
+ }
+
+ private static int toByte(char c) {
+ if (c >= '0' && c <= '9') return (c - '0');
+ if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
+ if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
+
+ throw new RuntimeException("Invalid hex char '" + c + "'");
+ }
+
+ private static byte[] hexStringToByteArray(String hexString) {
+ int length = hexString.length();
+ byte[] buffer = new byte[length / 2];
+
+ for (int i = 0; i < length; i += 2) {
+ buffer[i / 2] =
+ (byte) ((toByte(hexString.charAt(i)) << 4) | toByte(hexString.charAt(i + 1)));
+ }
+
+ return buffer;
+ }
}
diff --git a/pandora/interfaces/pandora_experimental/vcp.proto b/pandora/interfaces/pandora_experimental/vcp.proto
new file mode 100644
index 0000000000..42641c8545
--- /dev/null
+++ b/pandora/interfaces/pandora_experimental/vcp.proto
@@ -0,0 +1,47 @@
+// Copyright (C) 2024 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.
+
+syntax = "proto3";
+
+package pandora.vcp;
+
+import "pandora/host.proto";
+option java_outer_classname = "VcpProto";
+import "google/protobuf/empty.proto";
+
+service VCP {
+ // set absolute volume on remote device
+ rpc SetDeviceVolume(SetDeviceVolumeRequest) returns (google.protobuf.Empty);
+ // set volume offset on remote device
+ rpc SetVolumeOffset(SetVolumeOffsetRequest) returns (google.protobuf.Empty);
+ // Wait for device to be connected.
+ rpc WaitConnect(WaitConnectRequest) returns (google.protobuf.Empty);
+}
+
+// Request of the `SetDeviceVolume` method
+message SetDeviceVolumeRequest{
+ // Connection crafted by grpc server
+ Connection connection = 1;
+ // Volume value to be set
+ int32 volume = 2;
+}
+
+// Request of the `SetVolumeOffset` method
+message SetVolumeOffsetRequest{
+ // Connection crafted by grpc server
+ Connection connection = 1;
+ // Volume offset value to be set
+ int32 offset = 2;
+}
+
+message WaitConnectRequest {
+ Connection connection = 1;
+}
diff --git a/pandora/interfaces/python/Android.bp b/pandora/interfaces/python/Android.bp
index d295f2cfd3..c866c4a138 100644
--- a/pandora/interfaces/python/Android.bp
+++ b/pandora/interfaces/python/Android.bp
@@ -95,6 +95,10 @@ genrule {
"pandora_experimental/rfcomm_grpc_aio.py",
"pandora_experimental/rfcomm_pb2.py",
"pandora_experimental/rfcomm_pb2.pyi",
+ "pandora_experimental/vcp_grpc.py",
+ "pandora_experimental/vcp_grpc_aio.py",
+ "pandora_experimental/vcp_pb2.py",
+ "pandora_experimental/vcp_pb2.pyi",
],
}
@@ -129,6 +133,7 @@ filegroup {
":pandora_experimental-python-gen-src{pandora_experimental/pbap_pb2.pyi}",
":pandora_experimental-python-gen-src{pandora_experimental/py.typed}",
":pandora_experimental-python-gen-src{pandora_experimental/rfcomm_pb2.pyi}",
+ ":pandora_experimental-python-gen-src{pandora_experimental/vcp_pb2.pyi}",
],
}
diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
index b59ab9de45..8bd003641d 100644
--- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java
+++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java
@@ -142,7 +142,7 @@ class BluetoothManagerService {
// Delay for the addProxy function in msec
private static final int ADD_PROXY_DELAY_MS = 100 * HW_MULTIPLIER;
// Delay for retrying enable and disable in msec
- private static final int ENABLE_DISABLE_DELAY_MS = 300 * HW_MULTIPLIER;
+ @VisibleForTesting static final int ENABLE_DISABLE_DELAY_MS = 300 * HW_MULTIPLIER;
@VisibleForTesting static final int MESSAGE_ENABLE = 1;
@VisibleForTesting static final int MESSAGE_DISABLE = 2;
@@ -157,10 +157,8 @@ class BluetoothManagerService {
@VisibleForTesting static final int MESSAGE_GET_NAME_AND_ADDRESS = 200;
@VisibleForTesting static final int MESSAGE_USER_SWITCHED = 300;
@VisibleForTesting static final int MESSAGE_USER_UNLOCKED = 301;
- @VisibleForTesting static final int MESSAGE_RESTORE_USER_SETTING = 500;
-
- private static final int RESTORE_SETTING_TO_ON = 1;
- private static final int RESTORE_SETTING_TO_OFF = 0;
+ @VisibleForTesting static final int MESSAGE_RESTORE_USER_SETTING_OFF = 501;
+ @VisibleForTesting static final int MESSAGE_RESTORE_USER_SETTING_ON = 502;
private static final int MAX_ERROR_RESTART_RETRIES = 6;
private static final int MAX_WAIT_FOR_ENABLE_DISABLE_RETRIES = 10;
@@ -184,7 +182,7 @@ class BluetoothManagerService {
private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks =
new RemoteCallbackList<>();
private final BluetoothServiceBinder mBinder;
- private final BluetoothHandler mHandler;
+ @VisibleForTesting final BluetoothHandler mHandler;
private final ContentResolver mContentResolver;
private final Context mContext;
private final Looper mLooper;
@@ -401,39 +399,30 @@ class BluetoothManagerService {
private static final Object ON_SWITCH_USER_TOKEN = new Object();
Unit onAirplaneModeChanged(boolean isAirplaneModeOn) {
- mHandler.postDelayed(
- () ->
- delayModeChangedIfNeeded(
- ON_AIRPLANE_MODE_CHANGED_TOKEN,
- () -> handleAirplaneModeChanged(isAirplaneModeOn),
- "onAirplaneModeChanged"),
+ delayModeChangedIfNeeded(
ON_AIRPLANE_MODE_CHANGED_TOKEN,
- 0);
+ () -> handleAirplaneModeChanged(isAirplaneModeOn),
+ "onAirplaneModeChanged");
return Unit.INSTANCE;
}
// TODO(b/289584302): Update to private once use_new_satellite_mode is enabled
Unit onSatelliteModeChanged(boolean isSatelliteModeOn) {
- mHandler.postDelayed(
- () ->
- delayModeChangedIfNeeded(
- ON_SATELLITE_MODE_CHANGED_TOKEN,
- () -> handleSatelliteModeChanged(isSatelliteModeOn),
- "onSatelliteModeChanged"),
+ delayModeChangedIfNeeded(
ON_SATELLITE_MODE_CHANGED_TOKEN,
- 0);
+ () -> handleSatelliteModeChanged(isSatelliteModeOn),
+ "onSatelliteModeChanged");
return Unit.INSTANCE;
}
+ // Call is coming from the systemServer main thread and need to be post to avoid race
void onSwitchUser(UserHandle userHandle) {
- mHandler.postDelayed(
+ mHandler.post(
() ->
delayModeChangedIfNeeded(
ON_SWITCH_USER_TOKEN,
() -> handleSwitchUser(userHandle),
- "onSwitchUser"),
- ON_SWITCH_USER_TOKEN,
- 0);
+ "onSwitchUser"));
}
private void forceToOffFromModeChange(int currentState, int reason) {
@@ -460,29 +449,31 @@ class BluetoothManagerService {
}
private void handleAirplaneModeChanged(boolean isAirplaneModeOn) {
- synchronized (this) {
- if (isBluetoothPersistedStateOn()) {
- if (isAirplaneModeOn) {
- setBluetoothPersistedState(BLUETOOTH_ON_AIRPLANE);
- } else {
- setBluetoothPersistedState(BLUETOOTH_ON_BLUETOOTH);
- }
+ boolean isPersistStateOn = isBluetoothPersistedStateOn();
+ if (isPersistStateOn) {
+ if (isAirplaneModeOn) {
+ setBluetoothPersistedState(BLUETOOTH_ON_AIRPLANE);
+ } else {
+ setBluetoothPersistedState(BLUETOOTH_ON_BLUETOOTH);
}
+ }
- int currentState = mState.get();
+ int currentState = mState.get();
- Log.d(
- TAG,
- ("handleAirplaneModeChanged(" + isAirplaneModeOn + "):")
- + (" currentState=" + nameForState(currentState)));
-
- if (isAirplaneModeOn) {
- forceToOffFromModeChange(currentState, ENABLE_DISABLE_REASON_AIRPLANE_MODE);
- } else if (mEnableExternal) {
- sendEnableMsg(mQuietEnableExternal, ENABLE_DISABLE_REASON_AIRPLANE_MODE);
- } else if (currentState != STATE_ON) {
- autoOnSetupTimer();
- }
+ Log.d(
+ TAG,
+ ("handleAirplaneModeChanged(" + isAirplaneModeOn + "):")
+ + (" mEnableExternal=" + mEnableExternal)
+ + (" isPersistStateOn=" + isPersistStateOn)
+ + (" currentState=" + nameForState(currentState)));
+
+ if (isAirplaneModeOn) {
+ forceToOffFromModeChange(currentState, ENABLE_DISABLE_REASON_AIRPLANE_MODE);
+ } else if (mEnableExternal && currentState != STATE_ON && isPersistStateOn) {
+ // isPersistStateOn is checked to prevent race with RESTORE_USER_SETTING
+ sendEnableMsg(mQuietEnableExternal, ENABLE_DISABLE_REASON_AIRPLANE_MODE);
+ } else if (currentState != STATE_ON) {
+ autoOnSetupTimer();
}
}
@@ -557,17 +548,15 @@ class BluetoothManagerService {
+ (" prevValue=" + prevValue)
+ (" newValue=" + newValue));
- if ((newValue != null)
- && (prevValue != null)
- && !prevValue.equals(newValue)) {
- mHandler.obtainMessage(
- MESSAGE_RESTORE_USER_SETTING,
- newValue.equals("0")
- ? RESTORE_SETTING_TO_OFF
- : RESTORE_SETTING_TO_ON,
- 0)
- .sendToTarget();
+ if ((newValue == null)
+ || (prevValue == null)
+ || prevValue.equals(newValue)) {
+ return;
}
+ mHandler.sendEmptyMessage(
+ newValue.equals("0")
+ ? MESSAGE_RESTORE_USER_SETTING_OFF
+ : MESSAGE_RESTORE_USER_SETTING_ON);
}
} else if (action.equals(Intent.ACTION_SHUTDOWN)) {
Log.i(TAG, "Device is shutting down.");
@@ -1539,24 +1528,26 @@ class BluetoothManagerService {
}
break;
- case MESSAGE_RESTORE_USER_SETTING:
- if ((msg.arg1 == RESTORE_SETTING_TO_OFF) && mEnable) {
- Log.d(TAG, "MESSAGE_RESTORE_USER_SETTING: set Bluetooth state to disabled");
- setBluetoothPersistedState(BLUETOOTH_OFF);
- mEnableExternal = false;
- sendDisableMsg(ENABLE_DISABLE_REASON_RESTORE_USER_SETTING);
- } else if ((msg.arg1 == RESTORE_SETTING_TO_ON) && !mEnable) {
- Log.d(TAG, "MESSAGE_RESTORE_USER_SETTING: set Bluetooth state to enabled");
- mQuietEnableExternal = false;
- mEnableExternal = true;
- sendEnableMsg(false, ENABLE_DISABLE_REASON_RESTORE_USER_SETTING);
- } else {
- Log.w(
- TAG,
- "MESSAGE_RESTORE_USER_SETTING: Unhandled."
- + (" mEnable=" + mEnable)
- + (" msg.arg1=" + msg.arg1));
+ case MESSAGE_RESTORE_USER_SETTING_OFF:
+ if (!mEnable) {
+ Log.w(TAG, "RESTORE_USER_SETTING_OFF: Unhandled: already disabled");
+ break;
+ }
+ Log.d(TAG, "RESTORE_USER_SETTING_OFF: set Bluetooth state to disabled");
+ setBluetoothPersistedState(BLUETOOTH_OFF);
+ mEnableExternal = false;
+ sendDisableMsg(ENABLE_DISABLE_REASON_RESTORE_USER_SETTING);
+ break;
+
+ case MESSAGE_RESTORE_USER_SETTING_ON:
+ if (mEnable) {
+ Log.w(TAG, "RESTORE_USER_SETTING_ON: Unhandled: already enabled");
+ break;
}
+ Log.d(TAG, "RESTORE_USER_SETTING_ON: set Bluetooth state to enabled");
+ mQuietEnableExternal = false;
+ mEnableExternal = true;
+ sendEnableMsg(false, ENABLE_DISABLE_REASON_RESTORE_USER_SETTING);
break;
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
@@ -1618,14 +1609,10 @@ class BluetoothManagerService {
bluetoothStateChangeHandler(prevState, newState);
// handle error state transition case from TURNING_ON to OFF
// unbind and rebind bluetooth service and enable bluetooth
- if ((prevState == STATE_BLE_TURNING_ON)
- && (newState == STATE_OFF)
- && mEnable) {
+ if ((prevState == STATE_BLE_TURNING_ON) && (newState == STATE_OFF) && mEnable) {
recoverBluetoothServiceFromError(false);
}
- if ((prevState == STATE_TURNING_ON)
- && (newState == STATE_BLE_ON)
- && mEnable) {
+ if ((prevState == STATE_TURNING_ON) && (newState == STATE_BLE_ON) && mEnable) {
recoverBluetoothServiceFromError(true);
}
// If we tried to enable BT while BT was in the process of shutting down,
diff --git a/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java b/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java
index 4be1786c36..8c4a2c9fa8 100644
--- a/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java
+++ b/service/tests/src/com/android/server/bluetooth/BluetoothManagerServiceTest.java
@@ -19,6 +19,7 @@ package com.android.server.bluetooth;
import static android.bluetooth.BluetoothAdapter.STATE_BLE_ON;
import static android.bluetooth.BluetoothAdapter.STATE_OFF;
import static android.bluetooth.BluetoothAdapter.STATE_ON;
+import static android.bluetooth.BluetoothAdapter.STATE_TURNING_OFF;
import static android.bluetooth.BluetoothAdapter.STATE_TURNING_ON;
import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_BLUETOOTH_SERVICE_CONNECTED;
@@ -26,7 +27,9 @@ import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_BLUET
import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_BLUETOOTH_STATE_CHANGE;
import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_DISABLE;
import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_ENABLE;
+import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_HANDLE_DISABLE_DELAYED;
import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_RESTART_BLUETOOTH_SERVICE;
+import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_RESTORE_USER_SETTING_OFF;
import static com.android.server.bluetooth.BluetoothManagerService.MESSAGE_TIMEOUT_BIND;
import static com.google.common.truth.Truth.assertThat;
@@ -101,6 +104,7 @@ public class BluetoothManagerServiceTest {
}
private static final int STATE_BLE_TURNING_ON = 14; // can't find the symbol because hidden api
+ private static final int STATE_BLE_TURNING_OFF = 16; // can't find the symbol because hidden api
BluetoothManagerService mManagerService;
@@ -185,6 +189,7 @@ public class BluetoothManagerServiceTest {
doReturn(mAdapterBinder).when(mBluetoothServerProxy).createAdapterBinder(any());
doReturn(mAdapterService).when(mAdapterBinder).getAdapterBinder();
+ doReturn(mBinder).when(mAdapterService).asBinder();
doReturn(mock(Intent.class))
.when(mContext)
@@ -238,6 +243,17 @@ public class BluetoothManagerServiceTest {
});
}
+ private void discardMessage(int... what) {
+ IntStream.of(what)
+ .forEach(
+ w -> {
+ Message msg = mLooper.nextMessage();
+ assertThat(msg).isNotNull();
+ assertThat(msg.what).isEqualTo(w);
+ // Drop the message
+ });
+ }
+
@Test
public void onUserRestrictionsChanged_disallowBluetooth_onlySendDisableMessageOnSystemUser()
throws InterruptedException {
@@ -358,6 +374,22 @@ public class BluetoothManagerServiceTest {
return btCallback;
}
+ private void transition_onToBleOn(IBluetoothCallback btCallback) throws Exception {
+ verify(mAdapterBinder).onToBleOn(any());
+
+ btCallback.onBluetoothStateChange(STATE_TURNING_OFF, STATE_BLE_ON);
+ syncHandler(MESSAGE_BLUETOOTH_STATE_CHANGE);
+ }
+
+ private void transition_onToOff(IBluetoothCallback btCallback) throws Exception {
+ transition_onToBleOn(btCallback);
+ verify(mAdapterBinder).bleOnToOff(any());
+
+ // When all the profile are started, adapterService consider it is ON
+ btCallback.onBluetoothStateChange(STATE_BLE_TURNING_OFF, STATE_OFF);
+ syncHandler(MESSAGE_BLUETOOTH_STATE_CHANGE);
+ }
+
@Test
public void enable_whileTurningToBleOn_shouldEnable() throws Exception {
mManagerService.enableBle("enable_whileTurningToBleOn_shouldEnable", mBinder);
@@ -450,9 +482,47 @@ public class BluetoothManagerServiceTest {
assertThat(mManagerService.getState()).isEqualTo(STATE_OFF);
mLooper.moveTimeForward(120_000);
- Message msg = mLooper.nextMessage();
- assertThat(msg).isNotNull();
- assertThat(msg.what).isEqualTo(MESSAGE_RESTART_BLUETOOTH_SERVICE);
- // Discard the msg without executing it
+ discardMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
+ }
+
+ @Test
+ public void disableAirplane_whenNothing_startBluetooth() throws Exception {
+ doReturn(BluetoothManagerService.BLUETOOTH_ON_BLUETOOTH)
+ .when(mBluetoothServerProxy)
+ .getBluetoothPersistedState(any(), anyInt());
+ mManagerService.enable("disableAirplane_whenNothing_startBluetooth");
+ discardMessage(MESSAGE_ENABLE);
+
+ mManagerService.onAirplaneModeChanged(false);
+ discardMessage(MESSAGE_ENABLE);
+ }
+
+ @Test
+ public void disableAirplane_whenFactoryReset_doesNotStartBluetooth() throws Exception {
+ doAnswer(
+ invocation -> {
+ IBinder.DeathRecipient recipient = invocation.getArgument(0);
+ recipient.binderDied();
+ return null;
+ })
+ .when(mBinder)
+ .linkToDeath(any(), anyInt());
+
+ mManagerService.enable("test_offToOn");
+ syncHandler(MESSAGE_ENABLE);
+ IBluetoothCallback btCallback = transition_offToOn();
+ assertThat(mManagerService.getState()).isEqualTo(STATE_ON);
+
+ mManagerService.mHandler.sendEmptyMessage(MESSAGE_RESTORE_USER_SETTING_OFF);
+ syncHandler(MESSAGE_RESTORE_USER_SETTING_OFF);
+ syncHandler(MESSAGE_DISABLE);
+ mLooper.moveTimeForward(BluetoothManagerService.ENABLE_DISABLE_DELAY_MS);
+ syncHandler(MESSAGE_HANDLE_DISABLE_DELAYED);
+ mLooper.moveTimeForward(BluetoothManagerService.ENABLE_DISABLE_DELAY_MS);
+ syncHandler(MESSAGE_HANDLE_DISABLE_DELAYED);
+ transition_onToOff(btCallback);
+
+ mManagerService.onAirplaneModeChanged(false);
+ assertThat(mLooper.nextMessage()).isNull(); // Must not create a MESSAGE_ENABLE
}
}
diff --git a/system/Android.bp b/system/Android.bp
index b788868c0e..b79fa12489 100644
--- a/system/Android.bp
+++ b/system/Android.bp
@@ -307,11 +307,13 @@ cc_genrule {
":BlueberryFacadeAndCertGeneratedStub_py",
":bluetooth_cert_test_host_deps-zip",
":bluetooth_cert_test_sources-zip",
- ":bluetooth_cert_test_target_deps-zip",
":gd_hci_packets_python3_gen-zip",
":gd_smp_packets_python3_gen-zip",
":llvm-tools-zip",
],
+ device_first_srcs: [
+ ":bluetooth_cert_test_target_deps-zip",
+ ],
out: ["bluetooth_cert_tests.zip"],
cmd: "$(location merge_zips) $(genDir)/temp.zip $(in) && " +
"unzip -q -d $(genDir)/files $(genDir)/temp.zip && " +
diff --git a/system/audio_hal_interface/a2dp_encoding.h b/system/audio_hal_interface/a2dp_encoding.h
index d23d023e35..d1de4138b2 100644
--- a/system/audio_hal_interface/a2dp_encoding.h
+++ b/system/audio_hal_interface/a2dp_encoding.h
@@ -46,6 +46,8 @@ enum class BluetoothAudioStatus {
/// Implements callbacks for the BT Audio HAL to start, suspend and configure
/// the audio stream. Completion of the requested operation is indicated
/// by the methods ack_stream_started, ack_stream_suspended.
+///
+/// The callbacks are always invoked from one of the binder threads.
class BluetoothAudioPort {
public:
virtual ~BluetoothAudioPort() {}
diff --git a/system/audio_hal_interface/a2dp_encoding_host.cc b/system/audio_hal_interface/a2dp_encoding_host.cc
index e9bb187339..92f4361b78 100644
--- a/system/audio_hal_interface/a2dp_encoding_host.cc
+++ b/system/audio_hal_interface/a2dp_encoding_host.cc
@@ -27,7 +27,6 @@
#include "btif/include/btif_a2dp_source.h"
#include "btif/include/btif_av.h"
#include "btif/include/btif_hf.h"
-#include "os/log.h"
#include "stack/include/avdt_api.h"
#include "types/raw_address.h"
#include "udrv/include/uipc.h"
diff --git a/system/audio_hal_interface/aidl/a2dp/a2dp_encoding_aidl.h b/system/audio_hal_interface/aidl/a2dp/a2dp_encoding_aidl.h
index 32ef7923d8..f470d5e06a 100644
--- a/system/audio_hal_interface/aidl/a2dp/a2dp_encoding_aidl.h
+++ b/system/audio_hal_interface/aidl/a2dp/a2dp_encoding_aidl.h
@@ -22,7 +22,6 @@
#include "a2dp_sbc_constants.h"
#include "common/message_loop_thread.h"
#include "hardware/bt_av.h"
-#include "os/log.h"
#include "osi/include/properties.h"
#include "types/raw_address.h"
diff --git a/system/audio_hal_interface/aidl/a2dp/a2dp_provider_info.cc b/system/audio_hal_interface/aidl/a2dp/a2dp_provider_info.cc
index 9f4c86b2cf..074929290b 100644
--- a/system/audio_hal_interface/aidl/a2dp/a2dp_provider_info.cc
+++ b/system/audio_hal_interface/aidl/a2dp/a2dp_provider_info.cc
@@ -33,7 +33,6 @@
#include "a2dp_vendor_ldac_constants.h"
#include "a2dp_vendor_opus_constants.h"
#include "client_interface_aidl.h"
-#include "os/log.h"
namespace bluetooth::audio::aidl::a2dp {
diff --git a/system/audio_hal_interface/aidl/client_interface_aidl.cc b/system/audio_hal_interface/aidl/client_interface_aidl.cc
index 87e29cdab9..e8b143fb5d 100644
--- a/system/audio_hal_interface/aidl/client_interface_aidl.cc
+++ b/system/audio_hal_interface/aidl/client_interface_aidl.cc
@@ -135,8 +135,6 @@ void BluetoothAudioClientInterface::FetchAudioProvider() {
if (provider_ != nullptr) {
log::warn("refetch");
}
- // Prevent other access to the AIDL if currently fetching new service
- std::lock_guard<std::mutex> guard(internal_mutex_);
// Retry if audioserver restarts in the middle of fetching.
// When audioserver restarts, IBluetoothAudioProviderFactory service is also
// re-registered, so we need to re-fetch the service.
diff --git a/system/audio_hal_interface/aidl/hearing_aid_software_encoding_aidl.cc b/system/audio_hal_interface/aidl/hearing_aid_software_encoding_aidl.cc
index 64f4d3d6e4..b6a761889b 100644
--- a/system/audio_hal_interface/aidl/hearing_aid_software_encoding_aidl.cc
+++ b/system/audio_hal_interface/aidl/hearing_aid_software_encoding_aidl.cc
@@ -22,7 +22,6 @@
#include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
#include "client_interface_aidl.h"
-#include "os/log.h"
#include "osi/include/properties.h"
namespace fmt {
diff --git a/system/audio_hal_interface/aidl/le_audio_software_aidl.cc b/system/audio_hal_interface/aidl/le_audio_software_aidl.cc
index 8e3d8bfa03..7ba08289d0 100644
--- a/system/audio_hal_interface/aidl/le_audio_software_aidl.cc
+++ b/system/audio_hal_interface/aidl/le_audio_software_aidl.cc
@@ -28,7 +28,6 @@
#include <vector>
#include "hal_version_manager.h"
-#include "os/log.h"
namespace bluetooth {
namespace audio {
diff --git a/system/audio_hal_interface/hal_version_manager.cc b/system/audio_hal_interface/hal_version_manager.cc
index 19c48c58da..2068b766e9 100644
--- a/system/audio_hal_interface/hal_version_manager.cc
+++ b/system/audio_hal_interface/hal_version_manager.cc
@@ -24,7 +24,6 @@
#include <memory>
#include "aidl/audio_aidl_interfaces.h"
-#include "os/log.h"
namespace bluetooth {
namespace audio {
diff --git a/system/audio_hal_interface/hfp_client_interface.cc b/system/audio_hal_interface/hfp_client_interface.cc
index 22e6b99373..9ff47a3490 100644
--- a/system/audio_hal_interface/hfp_client_interface.cc
+++ b/system/audio_hal_interface/hfp_client_interface.cc
@@ -24,7 +24,6 @@
#include "aidl/hfp_client_interface_aidl.h"
#include "hal_version_manager.h"
#include "hfp_client_interface.h"
-#include "os/log.h"
#include "osi/include/properties.h"
using ::bluetooth::audio::aidl::hfp::HfpDecodingTransport;
diff --git a/system/audio_hal_interface/hidl/hearing_aid_software_encoding_hidl.cc b/system/audio_hal_interface/hidl/hearing_aid_software_encoding_hidl.cc
index 7f32ca7a2a..f80aac6b43 100644
--- a/system/audio_hal_interface/hidl/hearing_aid_software_encoding_hidl.cc
+++ b/system/audio_hal_interface/hidl/hearing_aid_software_encoding_hidl.cc
@@ -22,7 +22,6 @@
#include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
#include "client_interface_hidl.h"
-#include "os/log.h"
#include "osi/include/properties.h"
namespace fmt {
diff --git a/system/audio_hal_interface/hidl/le_audio_software_hidl.cc b/system/audio_hal_interface/hidl/le_audio_software_hidl.cc
index 94f8b8745b..740c05a0ad 100644
--- a/system/audio_hal_interface/hidl/le_audio_software_hidl.cc
+++ b/system/audio_hal_interface/hidl/le_audio_software_hidl.cc
@@ -21,8 +21,6 @@
#include <bluetooth/log.h>
-#include "os/log.h"
-
namespace bluetooth {
namespace audio {
namespace hidl {
diff --git a/system/audio_hal_interface/le_audio_software.cc b/system/audio_hal_interface/le_audio_software.cc
index 7061f865e6..a984d966ee 100644
--- a/system/audio_hal_interface/le_audio_software.cc
+++ b/system/audio_hal_interface/le_audio_software.cc
@@ -31,7 +31,6 @@
#include "bta/le_audio/le_audio_types.h"
#include "hal_version_manager.h"
#include "hidl/le_audio_software_hidl.h"
-#include "os/log.h"
#include "osi/include/properties.h"
namespace bluetooth {
diff --git a/system/bta/Android.bp b/system/bta/Android.bp
index 235246605f..4ffce6907d 100644
--- a/system/bta/Android.bp
+++ b/system/bta/Android.bp
@@ -260,6 +260,7 @@ cc_test {
":TestMockStackAvdt",
":TestMockStackAvrc",
":TestMockStackBtm",
+ ":TestMockStackConnMgr",
":TestMockStackGap",
":TestMockStackGatt",
":TestMockStackHid",
@@ -325,7 +326,7 @@ cc_test {
"libgmock",
"server_configurable_flags",
],
- data: [
+ device_first_data: [
":audio_set_configurations_bfbs",
":audio_set_configurations_json",
":audio_set_scenarios_bfbs",
@@ -791,7 +792,7 @@ cc_test {
"le_audio/le_audio_types.cc",
"le_audio/le_audio_utils.cc",
],
- data: [
+ device_first_data: [
":audio_set_configurations_bfbs",
":audio_set_configurations_json",
":audio_set_scenarios_bfbs",
@@ -900,7 +901,7 @@ cc_test {
"test/common/btm_api_mock.cc",
"test/common/mock_csis_client.cc",
],
- data: [
+ device_first_data: [
":audio_set_configurations_bfbs",
":audio_set_configurations_json",
":audio_set_scenarios_bfbs",
@@ -1026,7 +1027,7 @@ cc_test {
"libosi",
"server_configurable_flags",
],
- data: [
+ device_first_data: [
":audio_set_configurations_bfbs",
":audio_set_configurations_json",
":audio_set_scenarios_bfbs",
diff --git a/system/bta/ag/bta_ag_at.cc b/system/bta/ag/bta_ag_at.cc
index 2a7a24022d..a42017c29b 100644
--- a/system/bta/ag/bta_ag_at.cc
+++ b/system/bta/ag/bta_ag_at.cc
@@ -34,7 +34,6 @@
#include "bta/ag/bta_ag_int.h"
#include "bta/include/utl.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
using namespace bluetooth;
diff --git a/system/bta/ag/bta_ag_int.h b/system/bta/ag/bta_ag_int.h
index 2173d86d62..21d39365a3 100644
--- a/system/bta/ag/bta_ag_int.h
+++ b/system/bta/ag/bta_ag_int.h
@@ -34,6 +34,7 @@
#include "bta/include/bta_api.h"
#include "bta/sys/bta_sys.h"
#include "internal_include/bt_target.h"
+#include "os/logging/log_adapter.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/btm_api_types.h"
#include "stack/include/sdp_status.h"
diff --git a/system/bta/av/bta_av_act.cc b/system/bta/av/bta_av_act.cc
index fdc2cfcb98..a01920504d 100644
--- a/system/bta/av/bta_av_act.cc
+++ b/system/bta/av/bta_av_act.cc
@@ -321,7 +321,7 @@ static void bta_av_rc_msg_cback(uint8_t handle, uint8_t label, uint8_t opcode, t
* Returns the created rc handle
*
******************************************************************************/
-uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl, uint8_t lidx) {
+uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, tAVCT_ROLE role, uint8_t shdl, uint8_t lidx) {
if ((!btif_av_src_sink_coexist_enabled() ||
(btif_av_src_sink_coexist_enabled() && !btif_av_is_sink_enabled() &&
btif_av_is_source_enabled())) &&
@@ -330,14 +330,13 @@ uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl, uint8_t l
return BTA_AV_RC_HANDLE_NONE;
}
- tAVRC_CONN_CB ccb;
RawAddress bda = RawAddress::kAny;
uint8_t status = BTA_AV_RC_ROLE_ACP;
int i;
uint8_t rc_handle;
- tBTA_AV_RCB* p_rcb;
+ tBTA_AV_RCB* p_rcb{nullptr};
- if (role == AVCT_INT) {
+ if (role == AVCT_ROLE_INITIATOR) {
// Can't grab a stream control block that doesn't have a valid handle
if (!shdl) {
log::error("Can't grab stream control block for shdl = {} -> index = {}", shdl, shdl - 1);
@@ -357,14 +356,16 @@ uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl, uint8_t l
}
}
- ccb.ctrl_cback = base::Bind(bta_av_rc_ctrl_cback);
- ccb.msg_cback = base::Bind(bta_av_rc_msg_cback);
- ccb.company_id = p_bta_av_cfg->company_id;
- ccb.conn = role;
- /* note: BTA_AV_FEAT_RCTG = AVRC_CT_TARGET, BTA_AV_FEAT_RCCT = AVRC_CT_CONTROL
- */
- ccb.control = p_cb->features &
- (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_RCCT | BTA_AV_FEAT_METADATA | AVRC_CT_PASSIVE);
+ tAVRC_CONN_CB ccb = {
+ .ctrl_cback = base::Bind(bta_av_rc_ctrl_cback),
+ .msg_cback = base::Bind(bta_av_rc_msg_cback),
+ .company_id = p_bta_av_cfg->company_id,
+ .conn = role,
+ // note: BTA_AV_FEAT_RCTG = AVRC_CT_TARGET, BTA_AV_FEAT_RCCT = AVRC_CT_CONTROL
+ .control =
+ static_cast<uint8_t>(p_cb->features & (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_RCCT |
+ BTA_AV_FEAT_METADATA | AVRC_CT_PASSIVE)),
+ };
if (AVRC_Open(&rc_handle, &ccb, bda) != AVRC_SUCCESS) {
DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(bda, IOT_CONF_KEY_AVRCP_CONN_FAIL_COUNT);
@@ -392,8 +393,8 @@ uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl, uint8_t l
p_cb->rc_acp_idx = (i + 1);
log::verbose("rc_acp_handle:{} idx:{}", p_cb->rc_acp_handle, p_cb->rc_acp_idx);
}
- log::verbose("create {}, role: {}, shdl:{}, rc_handle:{}, lidx:{}, status:0x{:x}", i, role, shdl,
- p_rcb->handle, lidx, p_rcb->status);
+ log::verbose("create {}, role: {}, shdl:{}, rc_handle:{}, lidx:{}, status:0x{:x}", i,
+ avct_role_text(role), shdl, p_rcb->handle, lidx, p_rcb->status);
return rc_handle;
}
@@ -539,7 +540,7 @@ void bta_av_rc_opened(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) {
/* listen to browsing channel when the connection is open,
* if peer initiated AVRCP connection and local device supports browsing
* channel */
- AVRC_OpenBrowse(p_data->rc_conn_chg.handle, AVCT_ACP);
+ AVRC_OpenBrowse(p_data->rc_conn_chg.handle, AVCT_ROLE_ACCEPTOR);
if (p_cb->rcb[i].lidx == (BTA_AV_NUM_LINKS + 1) && shdl != 0) {
/* rc is opened on the RC only ACP channel, but is for a specific
@@ -618,7 +619,7 @@ void bta_av_rc_opened(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) {
(rc_open.peer_tg_features & BTA_AV_FEAT_BROWSE))) {
if ((p_cb->rcb[i].status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT) {
log::verbose("opening AVRC Browse channel");
- AVRC_OpenBrowse(p_data->rc_conn_chg.handle, AVCT_INT);
+ AVRC_OpenBrowse(p_data->rc_conn_chg.handle, AVCT_ROLE_INITIATOR);
}
}
return;
@@ -649,7 +650,7 @@ void bta_av_rc_opened(tBTA_AV_CB* p_cb, tBTA_AV_DATA* p_data) {
if ((p_cb->features & BTA_AV_FEAT_BROWSE) && (rc_open.peer_features & BTA_AV_FEAT_BROWSE) &&
((p_cb->rcb[i].status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT)) {
log::verbose("opening AVRC Browse channel");
- AVRC_OpenBrowse(p_data->rc_conn_chg.handle, AVCT_INT);
+ AVRC_OpenBrowse(p_data->rc_conn_chg.handle, AVCT_ROLE_INITIATOR);
}
}
@@ -1335,7 +1336,7 @@ void bta_av_conn_chg(tBTA_AV_DATA* p_data) {
/* if the AVRCP is no longer listening, create the listening channel */
if (bta_av_cb.rc_acp_handle == BTA_AV_RC_HANDLE_NONE && bta_av_cb.features & BTA_AV_FEAT_RCTG) {
- bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
+ bta_av_rc_create(&bta_av_cb, AVCT_ROLE_ACCEPTOR, 0, BTA_AV_NUM_LINKS + 1);
}
}
@@ -1554,7 +1555,7 @@ void bta_av_sig_chg(tBTA_AV_DATA* p_data) {
p_lcb->conn_msk = 0; /* clear the connect mask */
/* start listening when the signal channel is open */
if (p_cb->features & BTA_AV_FEAT_RCTG) {
- bta_av_rc_create(p_cb, AVCT_ACP, 0, p_lcb->lidx);
+ bta_av_rc_create(p_cb, AVCT_ROLE_ACCEPTOR, 0, p_lcb->lidx);
}
/* this entry is not used yet. */
p_cb->conn_lcb |= mask; /* mark it as used */
@@ -2118,7 +2119,8 @@ static void bta_av_rc_disc_done_all(tBTA_AV_DATA* /* p_data */) {
((p_cb->features & BTA_AV_FEAT_RCTG) && (peer_ct_features & BTA_AV_FEAT_RCCT))) {
p_lcb = bta_av_find_lcb(p_scb->PeerAddress(), BTA_AV_LCB_FIND);
if (p_lcb) {
- rc_handle = bta_av_rc_create(p_cb, AVCT_INT, (uint8_t)(p_scb->hdi + 1), p_lcb->lidx);
+ rc_handle = bta_av_rc_create(p_cb, AVCT_ROLE_INITIATOR, (uint8_t)(p_scb->hdi + 1),
+ p_lcb->lidx);
if (rc_handle != BTA_AV_RC_HANDLE_NONE) {
p_cb->rcb[rc_handle].peer_ct_features = peer_ct_features;
p_cb->rcb[rc_handle].peer_tg_features = peer_tg_features;
@@ -2302,7 +2304,8 @@ void bta_av_rc_disc_done(tBTA_AV_DATA* p_data) {
((p_cb->features & BTA_AV_FEAT_RCTG) && (peer_features & BTA_AV_FEAT_RCCT))) {
p_lcb = bta_av_find_lcb(p_scb->PeerAddress(), BTA_AV_LCB_FIND);
if (p_lcb) {
- rc_handle = bta_av_rc_create(p_cb, AVCT_INT, (uint8_t)(p_scb->hdi + 1), p_lcb->lidx);
+ rc_handle = bta_av_rc_create(p_cb, AVCT_ROLE_INITIATOR, (uint8_t)(p_scb->hdi + 1),
+ p_lcb->lidx);
if (rc_handle < BTA_AV_NUM_RCB) {
p_cb->rcb[rc_handle].peer_features = peer_features;
p_cb->rcb[rc_handle].cover_art_psm = cover_art_psm;
@@ -2484,7 +2487,7 @@ void bta_av_rc_closed(tBTA_AV_DATA* p_data) {
bta_av_data.rc_close = rc_close;
(*p_cb->p_cback)(BTA_AV_RC_CLOSE_EVT, &bta_av_data);
if (bta_av_cb.rc_acp_handle == BTA_AV_RC_HANDLE_NONE && bta_av_cb.features & BTA_AV_FEAT_RCTG) {
- bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
+ bta_av_rc_create(&bta_av_cb, AVCT_ROLE_ACCEPTOR, 0, BTA_AV_NUM_LINKS + 1);
}
}
diff --git a/system/bta/av/bta_av_api.cc b/system/bta/av/bta_av_api.cc
index 2c349e4334..0d3b26a086 100644
--- a/system/bta/av/bta_av_api.cc
+++ b/system/bta/av/bta_av_api.cc
@@ -32,7 +32,6 @@
#include "btif/include/btif_av.h"
#include "internal_include/bt_target.h"
#include "internal_include/bt_trace.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/compat.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/bta/av/bta_av_ci.cc b/system/bta/av/bta_av_ci.cc
index 2fa1afb079..7a83c8570a 100644
--- a/system/bta/av/bta_av_ci.cc
+++ b/system/bta/av/bta_av_ci.cc
@@ -30,7 +30,6 @@
#include <bluetooth/log.h>
#include "bta/av/bta_av_int.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/bta/av/bta_av_int.h b/system/bta/av/bta_av_int.h
index 94c63226e0..4f9773344e 100644
--- a/system/bta/av/bta_av_int.h
+++ b/system/bta/av/bta_av_int.h
@@ -37,6 +37,7 @@
#include "macros.h"
#include "osi/include/list.h"
#include "stack/include/a2dp_constants.h"
+#include "stack/include/avct_api.h"
#include "stack/include/avdt_api.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/hci_error_code.h"
@@ -526,7 +527,7 @@ public:
bool use_rc; /* true if AVRCP is allowed */
bool started; /* true if stream started */
bool use_rtp_header_marker_bit; /* true if the encoded data packets have RTP
- * headers, and the Marker bit in the header
+ * headers, with the Marker bit in the header
* is set according to RFC 6416 */
uint8_t co_started; /* non-zero, if stream started from call-out perspective */
bool recfg_sup; /* true if the first attempt to reconfigure the stream was
@@ -708,7 +709,7 @@ bool bta_av_chk_start(tBTA_AV_SCB* p_scb);
void bta_av_restore_switch(void);
void bta_av_conn_cback(uint8_t handle, const RawAddress& bd_addr, uint8_t event, tAVDT_CTRL* p_data,
uint8_t scb_index);
-uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, uint8_t role, uint8_t shdl, uint8_t lidx);
+uint8_t bta_av_rc_create(tBTA_AV_CB* p_cb, tAVCT_ROLE role, uint8_t shdl, uint8_t lidx);
void bta_av_stream_chg(tBTA_AV_SCB* p_scb, bool started);
bool bta_av_is_scb_opening(tBTA_AV_SCB* p_scb);
bool bta_av_is_scb_incoming(tBTA_AV_SCB* p_scb);
diff --git a/system/bta/av/bta_av_main.cc b/system/bta/av/bta_av_main.cc
index d8573d7f02..a992882a08 100644
--- a/system/bta/av/bta_av_main.cc
+++ b/system/bta/av/bta_av_main.cc
@@ -649,7 +649,7 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) {
}
/* start listening when A2DP is registered */
if (bta_av_cb.features & BTA_AV_FEAT_RCTG) {
- bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
+ bta_av_rc_create(&bta_av_cb, AVCT_ROLE_ACCEPTOR, 0, BTA_AV_NUM_LINKS + 1);
}
/* if the AV and AVK are both supported, it cannot support the CT role
@@ -658,7 +658,7 @@ static void bta_av_api_register(tBTA_AV_DATA* p_data) {
/* if TG is not supported, we need to register to AVCT now */
if ((bta_av_cb.features & (BTA_AV_FEAT_RCTG)) == 0) {
bta_ar_reg_avct();
- bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
+ bta_av_rc_create(&bta_av_cb, AVCT_ROLE_ACCEPTOR, 0, BTA_AV_NUM_LINKS + 1);
}
if (com::android::bluetooth::flags::avrcp_sdp_records()) {
// Add control record for sink profile.
diff --git a/system/bta/av/bta_av_ssm.cc b/system/bta/av/bta_av_ssm.cc
index 56c03a00cc..37df2021a2 100644
--- a/system/bta/av/bta_av_ssm.cc
+++ b/system/bta/av/bta_av_ssm.cc
@@ -28,7 +28,6 @@
#include "bta/av/bta_av_int.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
using namespace bluetooth;
diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc
index 1d1d5c589d..792aa44b6e 100644
--- a/system/bta/dm/bta_dm_act.cc
+++ b/system/bta/dm/bta_dm_act.cc
@@ -52,7 +52,7 @@
#include "main/shim/entry.h"
#include "osi/include/allocator.h"
#include "osi/include/properties.h"
-#include "stack/gatt/connection_manager.h"
+#include "stack/connection_manager/connection_manager.h"
#include "stack/include/acl_api.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_types.h"
diff --git a/system/bta/dm/bta_dm_pm.cc b/system/bta/dm/bta_dm_pm.cc
index dfd93ca2dc..ca3bb38058 100644
--- a/system/bta/dm/bta_dm_pm.cc
+++ b/system/bta/dm/bta_dm_pm.cc
@@ -39,7 +39,6 @@
#include "hci/controller_interface.h"
#include "main/shim/dumpsys.h"
#include "main/shim/entry.h"
-#include "os/log.h"
#include "osi/include/properties.h"
#include "stack/include/acl_api.h"
#include "stack/include/btm_client_interface.h"
diff --git a/system/bta/gatt/bta_gattc_api.cc b/system/bta/gatt/bta_gattc_api.cc
index d4dfc500b1..38b3691b4a 100644
--- a/system/bta/gatt/bta_gattc_api.cc
+++ b/system/bta/gatt/bta_gattc_api.cc
@@ -34,7 +34,6 @@
#include "bta/gatt/bta_gattc_int.h"
#include "gd/hci/uuid.h"
#include "gd/os/rand.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/main_thread.h"
diff --git a/system/bta/gatt/bta_gattc_db_storage.cc b/system/bta/gatt/bta_gattc_db_storage.cc
index 6a741e8544..34beb0852c 100644
--- a/system/bta/gatt/bta_gattc_db_storage.cc
+++ b/system/bta/gatt/bta_gattc_db_storage.cc
@@ -28,7 +28,6 @@
#include "bta/gatt/bta_gattc_int.h"
#include "gatt/database.h"
-#include "os/log.h"
#include "stack/include/gattdefs.h"
#include "types/bluetooth/uuid.h"
diff --git a/system/bta/gatt/bta_gattc_main.cc b/system/bta/gatt/bta_gattc_main.cc
index fc642edfd4..2912879e77 100644
--- a/system/bta/gatt/bta_gattc_main.cc
+++ b/system/bta/gatt/bta_gattc_main.cc
@@ -28,7 +28,6 @@
#include "bta/gatt/bta_gattc_int.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "stack/include/bt_hdr.h"
using base::StringPrintf;
diff --git a/system/bta/gatt/bta_gattc_queue.cc b/system/bta/gatt/bta_gattc_queue.cc
index 6d2cc8c887..40d99a7fb5 100644
--- a/system/bta/gatt/bta_gattc_queue.cc
+++ b/system/bta/gatt/bta_gattc_queue.cc
@@ -24,7 +24,6 @@
#include <vector>
#include "bta_gatt_queue.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/eatt/eatt.h"
diff --git a/system/bta/gatt/bta_gatts_queue.cc b/system/bta/gatt/bta_gatts_queue.cc
index 1344f036f0..ef6a73e9d9 100644
--- a/system/bta/gatt/bta_gatts_queue.cc
+++ b/system/bta/gatt/bta_gatts_queue.cc
@@ -23,7 +23,6 @@
#include <unordered_set>
#include "bta_gatt_server_queue.h"
-#include "os/log.h"
using gatts_operation = BtaGattServerQueue::gatts_operation;
using bluetooth::Uuid;
diff --git a/system/bta/gmap/gmap_client.cc b/system/bta/gmap/gmap_client.cc
index 7cd8d8c054..917070e2ac 100644
--- a/system/bta/gmap/gmap_client.cc
+++ b/system/bta/gmap/gmap_client.cc
@@ -33,7 +33,6 @@
#include "gap_api.h"
#include "gatt_api.h"
#include "internal_include/bt_trace.h"
-#include "os/log.h"
#include "osi/include/properties.h"
#include "stack/include/bt_types.h"
diff --git a/system/bta/gmap/gmap_server.cc b/system/bta/gmap/gmap_server.cc
index deb0e9cb3c..6d5ca2cd47 100644
--- a/system/bta/gmap/gmap_server.cc
+++ b/system/bta/gmap/gmap_server.cc
@@ -38,7 +38,6 @@
#include "gd/os/rand.h"
#include "include/hardware/bt_gmap.h"
#include "internal_include/bt_trace.h"
-#include "os/log.h"
#include "os/logging/log_adapter.h"
#include "osi/include/properties.h"
#include "stack/include/bt_types.h"
diff --git a/system/bta/has/has_client.cc b/system/bta/has/has_client.cc
index de671e9dfa..15f69ab76a 100644
--- a/system/bta/has/has_client.cc
+++ b/system/bta/has/has_client.cc
@@ -39,7 +39,6 @@
#include "gatt_api.h"
#include "has_types.h"
#include "internal_include/bt_trace.h"
-#include "os/log.h"
#include "osi/include/properties.h"
#include "stack/include/bt_types.h"
diff --git a/system/bta/has/has_ctp.cc b/system/bta/has/has_ctp.cc
index 080298fc9e..c39bef152a 100644
--- a/system/bta/has/has_ctp.cc
+++ b/system/bta/has/has_ctp.cc
@@ -19,7 +19,7 @@
#include <bluetooth/log.h>
-#include "os/log.h"
+#include "os/logging/log_adapter.h"
#include "stack/include/bt_types.h"
using namespace bluetooth;
diff --git a/system/bta/hd/bta_hd_api.cc b/system/bta/hd/bta_hd_api.cc
index 09c353b7df..3f5d3827a2 100644
--- a/system/bta/hd/bta_hd_api.cc
+++ b/system/bta/hd/bta_hd_api.cc
@@ -32,7 +32,6 @@
#include <bluetooth/log.h>
#include "bta/hd/bta_hd_int.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/compat.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/bta/hearing_aid/hearing_aid_audio_source.cc b/system/bta/hearing_aid/hearing_aid_audio_source.cc
index 429bb4f0ce..ccc6708079 100644
--- a/system/bta/hearing_aid/hearing_aid_audio_source.cc
+++ b/system/bta/hearing_aid/hearing_aid_audio_source.cc
@@ -29,7 +29,6 @@
#include "bta/include/bta_hearing_aid_api.h"
#include "common/repeating_timer.h"
#include "common/time_util.h"
-#include "os/log.h"
#include "osi/include/wakelock.h"
#include "stack/include/main_thread.h"
#include "udrv/include/uipc.h"
diff --git a/system/bta/hf_client/bta_hf_client_at.cc b/system/bta/hf_client/bta_hf_client_at.cc
index 9be68cab97..883d0f0955 100644
--- a/system/bta/hf_client/bta_hf_client_at.cc
+++ b/system/bta/hf_client/bta_hf_client_at.cc
@@ -23,7 +23,6 @@
#include "bta/hf_client/bta_hf_client_int.h"
#include "internal_include/bt_trace.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/compat.h"
#include "osi/include/properties.h"
diff --git a/system/bta/hf_client/bta_hf_client_sdp.cc b/system/bta/hf_client/bta_hf_client_sdp.cc
index a9dc87489c..94ebd87917 100644
--- a/system/bta/hf_client/bta_hf_client_sdp.cc
+++ b/system/bta/hf_client/bta_hf_client_sdp.cc
@@ -33,7 +33,6 @@
#include "bta/include/bta_rfcomm_scn.h"
#include "bta/sys/bta_sys.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_types.h"
#include "stack/include/bt_uuid16.h"
diff --git a/system/bta/hh/bta_hh_api.cc b/system/bta/hh/bta_hh_api.cc
index 10ca7f2d65..413eeb9b6d 100644
--- a/system/bta/hh/bta_hh_api.cc
+++ b/system/bta/hh/bta_hh_api.cc
@@ -30,7 +30,6 @@
#include "bta/hh/bta_hh_int.h"
#include "bta/sys/bta_sys.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/main_thread.h"
diff --git a/system/bta/hh/bta_hh_main.cc b/system/bta/hh/bta_hh_main.cc
index a4dd1444b4..1601663573 100644
--- a/system/bta/hh/bta_hh_main.cc
+++ b/system/bta/hh/bta_hh_main.cc
@@ -31,7 +31,6 @@
#include "bta/hh/bta_hh_int.h"
#include "main/shim/dumpsys.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/bta/hh/bta_hh_utils.cc b/system/bta/hh/bta_hh_utils.cc
index c163c1e5ab..b5b86cf94d 100644
--- a/system/bta/hh/bta_hh_utils.cc
+++ b/system/bta/hh/bta_hh_utils.cc
@@ -26,7 +26,6 @@
#include "btif/include/btif_storage.h"
#include "device/include/interop.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/btm_client_interface.h"
#include "stack/include/btm_status.h"
diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h
index 43f5fc1d72..8772fe183c 100644
--- a/system/bta/include/bta_api.h
+++ b/system/bta/include/bta_api.h
@@ -35,7 +35,6 @@
#include "bta_api_data_types.h"
#include "hci/le_rand_callback.h"
#include "macros.h"
-#include "os/log.h"
#include "stack/btm/btm_eir.h"
#include "stack/btm/power_mode.h"
#include "stack/include/bt_dev_class.h"
diff --git a/system/bta/jv/bta_jv_act.cc b/system/bta/jv/bta_jv_act.cc
index 852204ed61..cb00b7b6f8 100644
--- a/system/bta/jv/bta_jv_act.cc
+++ b/system/bta/jv/bta_jv_act.cc
@@ -38,8 +38,6 @@
#include "osi/include/allocator.h"
#include "osi/include/properties.h"
#include "stack/btm/btm_sec.h"
-#include "stack/include/avct_api.h" // AVCT_PSM
-#include "stack/include/avdt_api.h" // AVDT_PSM
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_psm_types.h"
#include "stack/include/bt_types.h"
@@ -621,8 +619,8 @@ bool bta_jv_check_psm(uint16_t psm) {
}
break;
- case AVCT_PSM: /* 0x17 */
- case AVDT_PSM: /* 0x19 */
+ case BT_PSM_AVCTP: /* 0x17 */
+ case BT_PSM_AVDTP: /* 0x19 */
if (!bta_sys_is_register(BTA_ID_AV)) {
ret = true;
}
diff --git a/system/bta/le_audio/audio_hal_client/audio_sink_hal_client.cc b/system/bta/le_audio/audio_hal_client/audio_sink_hal_client.cc
index 8f05b7248b..2f86a94e5b 100644
--- a/system/bta/le_audio/audio_hal_client/audio_sink_hal_client.cc
+++ b/system/bta/le_audio/audio_hal_client/audio_sink_hal_client.cc
@@ -24,7 +24,6 @@
#include "audio_hal_interface/le_audio_software.h"
#include "bta/le_audio/codec_manager.h"
#include "common/time_util.h"
-#include "os/log.h"
#include "osi/include/wakelock.h"
#include "stack/include/main_thread.h"
diff --git a/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc b/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc
index b721d4546d..bd7c8bea85 100644
--- a/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc
+++ b/system/bta/le_audio/audio_hal_client/audio_source_hal_client.cc
@@ -30,7 +30,6 @@
#include "common/repeating_timer.h"
#include "common/time_util.h"
#include "gd/hal/link_clocker.h"
-#include "os/log.h"
#include "osi/include/wakelock.h"
#include "stack/include/main_thread.h"
diff --git a/system/bta/le_audio/broadcaster/broadcaster.cc b/system/bta/le_audio/broadcaster/broadcaster.cc
index a7b05339b1..251091a8b4 100644
--- a/system/bta/le_audio/broadcaster/broadcaster.cc
+++ b/system/bta/le_audio/broadcaster/broadcaster.cc
@@ -913,13 +913,16 @@ public:
is_iso_running_ = is_active;
log::info("is_iso_running: {}", is_iso_running_);
if (!is_iso_running_) {
- if (queued_start_broadcast_request_) {
- auto broadcast_id = *queued_start_broadcast_request_;
- queued_start_broadcast_request_ = std::nullopt;
+ if (!com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
+ if (queued_start_broadcast_request_) {
+ auto broadcast_id = *queued_start_broadcast_request_;
+ queued_start_broadcast_request_ = std::nullopt;
- log::info("Start queued broadcast.");
- StartAudioBroadcast(broadcast_id);
+ log::info("Start queued broadcast.");
+ StartAudioBroadcast(broadcast_id);
+ }
}
+
if (queued_create_broadcast_request_) {
auto broadcast_msg = std::move(*queued_create_broadcast_request_);
queued_create_broadcast_request_ = std::nullopt;
diff --git a/system/bta/le_audio/broadcaster/broadcaster_test.cc b/system/bta/le_audio/broadcaster/broadcaster_test.cc
index 1145b93a4a..63b708039e 100644
--- a/system/bta/le_audio/broadcaster/broadcaster_test.cc
+++ b/system/bta/le_audio/broadcaster/broadcaster_test.cc
@@ -533,8 +533,19 @@ TEST_F(BroadcasterTest, CreateAudioBroadcastMultiGroups) {
TEST_F(BroadcasterTest, SuspendAudioBroadcast) {
EXPECT_CALL(*mock_codec_manager_, UpdateActiveBroadcastAudioHalClient(mock_audio_source_, true))
.Times(1);
+ LeAudioSourceAudioHalClient::Callbacks* audio_receiver;
+ EXPECT_CALL(*mock_audio_source_, Start)
+ .WillOnce(DoAll(SaveArg<1>(&audio_receiver), Return(true)))
+ .WillRepeatedly(Return(false));
auto broadcast_id = InstantiateBroadcast();
- LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
+
+ if (com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
+ ASSERT_NE(audio_receiver, nullptr);
+ audio_receiver->OnAudioResume();
+ } else {
+ LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
+ }
+
Mock::VerifyAndClearExpectations(mock_codec_manager_);
EXPECT_CALL(mock_broadcaster_callbacks_,
@@ -559,7 +570,9 @@ TEST_F(BroadcasterTest, StartAudioBroadcast) {
EXPECT_CALL(*mock_codec_manager_, UpdateActiveBroadcastAudioHalClient(mock_audio_source_, true))
.Times(1);
+
auto broadcast_id = InstantiateBroadcast();
+ ASSERT_NE(audio_receiver, nullptr);
Mock::VerifyAndClearExpectations(mock_codec_manager_);
EXPECT_CALL(*mock_codec_manager_, UpdateActiveBroadcastAudioHalClient(mock_audio_source_, true))
@@ -575,8 +588,7 @@ TEST_F(BroadcasterTest, StartAudioBroadcast) {
ASSERT_TRUE(big_terminate_timer_->cb == nullptr);
ASSERT_TRUE(broadcast_stop_timer_->cb == nullptr);
- LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
- ASSERT_NE(audio_receiver, nullptr);
+ audio_receiver->OnAudioResume();
// NOTICE: This is really an implementation specific part, we fake the BIG
// config as the mocked state machine does not even call the
@@ -609,6 +621,7 @@ TEST_F(BroadcasterTest, StartAudioBroadcastMedia) {
.Times(1);
auto broadcast_id =
InstantiateBroadcast(media_metadata, default_code, {bluetooth::le_audio::QUALITY_HIGH});
+ ASSERT_NE(audio_receiver, nullptr);
Mock::VerifyAndClearExpectations(mock_codec_manager_);
LeAudioBroadcaster::Get()->StopAudioBroadcast(broadcast_id);
@@ -626,8 +639,7 @@ TEST_F(BroadcasterTest, StartAudioBroadcastMedia) {
EXPECT_CALL(*mock_codec_manager_, UpdateActiveBroadcastAudioHalClient(mock_audio_source_, false))
.Times(0);
- LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
- ASSERT_NE(audio_receiver, nullptr);
+ audio_receiver->OnAudioResume();
// NOTICE: This is really an implementation specific part, we fake the BIG
// config as the mocked state machine does not even call the
@@ -651,8 +663,18 @@ TEST_F(BroadcasterTest, StartAudioBroadcastMedia) {
TEST_F(BroadcasterTest, StopAudioBroadcast) {
EXPECT_CALL(*mock_codec_manager_, UpdateActiveBroadcastAudioHalClient(mock_audio_source_, true))
.Times(1);
+ LeAudioSourceAudioHalClient::Callbacks* audio_receiver;
+ EXPECT_CALL(*mock_audio_source_, Start)
+ .WillOnce(DoAll(SaveArg<1>(&audio_receiver), Return(true)))
+ .WillRepeatedly(Return(false));
auto broadcast_id = InstantiateBroadcast();
- LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
+
+ if (com::android::bluetooth::flags::leaudio_big_depends_on_audio_state()) {
+ ASSERT_NE(audio_receiver, nullptr);
+ audio_receiver->OnAudioResume();
+ } else {
+ LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
+ }
// NOTICE: This is really an implementation specific part, we fake the BIG
// config as the mocked state machine does not even call the
@@ -712,7 +734,6 @@ TEST_F(BroadcasterTest, DestroyAudioBroadcast) {
LeAudioBroadcaster::Get()->StopAudioBroadcast(broadcast_id);
EXPECT_CALL(*mock_audio_source_, Start).Times(0);
- LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
EXPECT_CALL(*mock_audio_source_, Stop).Times(0);
LeAudioBroadcaster::Get()->SuspendAudioBroadcast(broadcast_id);
@@ -846,8 +867,8 @@ TEST_F(BroadcasterTest, UpdateMetadataFromAudioTrackMetadata) {
ContentControlIdKeeper::GetInstance()->SetCcid(LeAudioContextType::MEDIA, media_ccid);
auto broadcast_id = InstantiateBroadcast();
- LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
ASSERT_NE(audio_receiver, nullptr);
+ audio_receiver->OnAudioResume();
auto sm = MockBroadcastStateMachine::GetLastInstance();
std::vector<uint8_t> ccid_list;
@@ -1204,6 +1225,7 @@ TEST_F(BroadcasterTest, AudioActiveState) {
.WillRepeatedly(Return(false));
auto broadcast_id = InstantiateBroadcast();
+ ASSERT_NE(audio_receiver, nullptr);
auto sm = MockBroadcastStateMachine::GetLastInstance();
pb_announcement = sm->GetPublicBroadcastAnnouncement();
auto created_public_meta = types::LeAudioLtvMap(pb_announcement.metadata).RawPacket();
@@ -1218,9 +1240,6 @@ TEST_F(BroadcasterTest, AudioActiveState) {
});
ON_CALL(*sm, GetPublicBroadcastAnnouncement()).WillByDefault(ReturnRef(pb_announcement));
- LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
- ASSERT_NE(audio_receiver, nullptr);
-
// Update to true Audio Active State while audio resumed
EXPECT_CALL(*sm, UpdatePublicBroadcastAnnouncement);
audio_receiver->OnAudioResume();
@@ -1278,32 +1297,12 @@ TEST_F(BroadcasterTest, BigTerminationAndBroadcastStopWhenNoSoundFromTheBeginnin
auto broadcast_id = InstantiateBroadcast();
EXPECT_CALL(mock_broadcaster_callbacks_,
OnBroadcastStateChanged(broadcast_id, BroadcastState::STREAMING))
- .Times(1);
+ .Times(0);
// Timers not started
ASSERT_TRUE(big_terminate_timer_->cb == nullptr);
ASSERT_TRUE(broadcast_stop_timer_->cb == nullptr);
-
- // Start Broadcast
- LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
- // Timers started
- ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
- ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
- ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);
+ ASSERT_EQ(0, get_func_call_count("alarm_set_on_mloop"));
ASSERT_NE(audio_receiver, nullptr);
-
- // BIG termination timer execution, state machine go to CONFIGURED state so BIG terminated
- EXPECT_CALL(mock_broadcaster_callbacks_,
- OnBroadcastStateChanged(broadcast_id, BroadcastState::CONFIGURED))
- .Times(1);
- // Imitate execution of BIG termination timer
- big_terminate_timer_->cb(big_terminate_timer_->data);
-
- // Broadcast stop timer execution, state machine go to STOPPED state
- EXPECT_CALL(mock_broadcaster_callbacks_,
- OnBroadcastStateChanged(broadcast_id, BroadcastState::STOPPED))
- .Times(1);
- // Imitate execution of BIG termination timer
- broadcast_stop_timer_->cb(broadcast_stop_timer_->data);
}
TEST_F(BroadcasterTest, BigTerminationAndBroadcastStopWhenNoSoundAfterSuspend) {
@@ -1326,24 +1325,11 @@ TEST_F(BroadcasterTest, BigTerminationAndBroadcastStopWhenNoSoundAfterSuspend) {
ASSERT_TRUE(broadcast_stop_timer_->cb == nullptr);
// Start Broadcast
- LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
- // Timers started
- ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
- ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
- ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);
- ASSERT_NE(audio_receiver, nullptr);
-
- // First onAudioResume when BIG already created, not cause any state change
- EXPECT_CALL(mock_broadcaster_callbacks_, OnBroadcastStateChanged(broadcast_id, _)).Times(0);
audio_receiver->OnAudioResume();
- // Timers cancelled
- ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
- ASSERT_TRUE(big_terminate_timer_->cb == nullptr);
- ASSERT_TRUE(broadcast_stop_timer_->cb == nullptr);
// OnAudioSuspend cause starting the BIG termination timer
audio_receiver->OnAudioSuspend();
- ASSERT_EQ(4, get_func_call_count("alarm_set_on_mloop"));
+ ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);
@@ -1357,7 +1343,7 @@ TEST_F(BroadcasterTest, BigTerminationAndBroadcastStopWhenNoSoundAfterSuspend) {
// OnAudioSuspend cause starting the BIG termination timer
audio_receiver->OnAudioSuspend();
- ASSERT_EQ(6, get_func_call_count("alarm_set_on_mloop"));
+ ASSERT_EQ(4, get_func_call_count("alarm_set_on_mloop"));
ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);
@@ -1396,24 +1382,11 @@ TEST_F(BroadcasterTest, BigCreationTerminationDependsOnAudioResumeSuspend) {
ASSERT_TRUE(broadcast_stop_timer_->cb == nullptr);
// Start Broadcast
- LeAudioBroadcaster::Get()->StartAudioBroadcast(broadcast_id);
- // Timers started
- ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
- ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
- ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);
- ASSERT_NE(audio_receiver, nullptr);
-
- // First onAudioResume when BIG already created, not cause any state change
- EXPECT_CALL(mock_broadcaster_callbacks_, OnBroadcastStateChanged(broadcast_id, _)).Times(0);
audio_receiver->OnAudioResume();
- // Timers cancelled
- ASSERT_EQ(2, get_func_call_count("alarm_cancel"));
- ASSERT_TRUE(big_terminate_timer_->cb == nullptr);
- ASSERT_TRUE(broadcast_stop_timer_->cb == nullptr);
// OnAudioSuspend cause starting the BIG termination timer
audio_receiver->OnAudioSuspend();
- ASSERT_EQ(4, get_func_call_count("alarm_set_on_mloop"));
+ ASSERT_EQ(2, get_func_call_count("alarm_set_on_mloop"));
ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);
@@ -1427,7 +1400,7 @@ TEST_F(BroadcasterTest, BigCreationTerminationDependsOnAudioResumeSuspend) {
// OnAudioSuspend cause starting the BIG termination timer
audio_receiver->OnAudioSuspend();
- ASSERT_EQ(6, get_func_call_count("alarm_set_on_mloop"));
+ ASSERT_EQ(4, get_func_call_count("alarm_set_on_mloop"));
ASSERT_TRUE(big_terminate_timer_->cb != nullptr);
ASSERT_TRUE(broadcast_stop_timer_->cb != nullptr);
diff --git a/system/bta/le_audio/broadcaster/mock_state_machine.h b/system/bta/le_audio/broadcaster/mock_state_machine.h
index ebafbed398..6b35b11532 100644
--- a/system/bta/le_audio/broadcaster/mock_state_machine.h
+++ b/system/bta/le_audio/broadcaster/mock_state_machine.h
@@ -30,6 +30,7 @@ public:
advertising_sid_ = ++instance_counter_;
ON_CALL(*this, Initialize).WillByDefault([this]() {
+ SetState(State::CONFIGURED);
this->cb->OnStateMachineCreateStatus(this->cfg.broadcast_id, result_);
return result_;
});
diff --git a/system/bta/le_audio/broadcaster/state_machine.cc b/system/bta/le_audio/broadcaster/state_machine.cc
index 07c258683a..d81011b655 100644
--- a/system/bta/le_audio/broadcaster/state_machine.cc
+++ b/system/bta/le_audio/broadcaster/state_machine.cc
@@ -30,7 +30,6 @@
#include "bta/le_audio/le_audio_types.h"
#include "common/strings.h"
#include "hci/le_advertising_manager.h"
-#include "os/log.h"
#include "osi/include/properties.h"
#include "stack/include/btm_iso_api.h"
diff --git a/system/bta/le_audio/client.cc b/system/bta/le_audio/client.cc
index e76c7eee2d..01c2856e99 100644
--- a/system/bta/le_audio/client.cc
+++ b/system/bta/le_audio/client.cc
@@ -365,6 +365,36 @@ public:
}
}
+ void StartSuspendTimeout(void) {
+ StopSuspendTimeout();
+
+ /* Group should tie in time to get requested status */
+ uint64_t timeoutMs = kAudioSuspentKeepIsoAliveTimeoutMs;
+ timeoutMs = osi_property_get_int32(kAudioSuspentKeepIsoAliveTimeoutMsProp, timeoutMs);
+
+ if (stack_config_get_interface()->get_pts_le_audio_disable_ases_before_stopping()) {
+ timeoutMs += kAudioDisableTimeoutMs;
+ }
+
+ log::debug("Stream suspend_timeout_ started: {} ms", static_cast<int>(timeoutMs));
+
+ alarm_set_on_mloop(
+ suspend_timeout_, timeoutMs,
+ [](void* data) {
+ if (instance) {
+ instance->GroupStop(PTR_TO_INT(data));
+ }
+ },
+ INT_TO_PTR(active_group_id_));
+ }
+
+ void StopSuspendTimeout(void) {
+ if (alarm_is_scheduled(suspend_timeout_)) {
+ log::debug("Cancel suspend timeout");
+ alarm_cancel(suspend_timeout_);
+ }
+ }
+
void AseInitialStateReadRequest(LeAudioDevice* leAudioDevice) {
int ases_num = leAudioDevice->ases_.size();
void* notify_flag_ptr = NULL;
@@ -1292,9 +1322,7 @@ public:
sink_monitor_notified_status_ = std::nullopt;
log::info("Group id: {}", active_group_id_);
- if (alarm_is_scheduled(suspend_timeout_)) {
- alarm_cancel(suspend_timeout_);
- }
+ StopSuspendTimeout();
StopAudio();
ClientAudioInterfaceRelease();
@@ -3921,9 +3949,7 @@ public:
void Cleanup() {
StopVbcCloseTimeout();
- if (alarm_is_scheduled(suspend_timeout_)) {
- alarm_cancel(suspend_timeout_);
- }
+ StopSuspendTimeout();
if (active_group_id_ != bluetooth::groups::kGroupUnknown) {
/* Bluetooth turned off while streaming */
@@ -4037,27 +4063,7 @@ public:
INT_TO_PTR(active_group_id_));
}
- /* Group should tie in time to get requested status */
- uint64_t timeoutMs = kAudioSuspentKeepIsoAliveTimeoutMs;
- timeoutMs = osi_property_get_int32(kAudioSuspentKeepIsoAliveTimeoutMsProp, timeoutMs);
-
- if (stack_config_get_interface()->get_pts_le_audio_disable_ases_before_stopping()) {
- timeoutMs += kAudioDisableTimeoutMs;
- }
-
- log::debug("Stream suspend_timeout_ started: {} ms", static_cast<int>(timeoutMs));
- if (alarm_is_scheduled(suspend_timeout_)) {
- alarm_cancel(suspend_timeout_);
- }
-
- alarm_set_on_mloop(
- suspend_timeout_, timeoutMs,
- [](void* data) {
- if (instance) {
- instance->GroupStop(PTR_TO_INT(data));
- }
- },
- INT_TO_PTR(active_group_id_));
+ StartSuspendTimeout();
}
void OnLocalAudioSourceSuspend() {
@@ -4215,6 +4221,7 @@ public:
if (group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
if (IsDirectionAvailableForCurrentConfiguration(
group, bluetooth::le_audio::types::kLeAudioDirectionSink)) {
+ StopSuspendTimeout();
StartSendingAudio(active_group_id_);
} else {
log::warn(
@@ -4255,9 +4262,7 @@ public:
case AudioState::IDLE:
case AudioState::READY_TO_RELEASE:
/* Stream is up just restore it */
- if (alarm_is_scheduled(suspend_timeout_)) {
- alarm_cancel(suspend_timeout_);
- }
+ StopSuspendTimeout();
ConfirmLocalAudioSourceStreamingRequest();
bluetooth::le_audio::MetricsCollector::Get()->OnStreamStarted(
active_group_id_, configuration_context_type_);
@@ -4282,8 +4287,6 @@ public:
"r_state: " + ToString(audio_receiver_state_) +
", s_state: " + ToString(audio_sender_state_));
- StartVbcCloseTimeout();
-
/* Note: This callback is from audio hal driver.
* Bluetooth peer is a Source for Audio Framework.
* e.g. Peer is microphone.
@@ -4308,6 +4311,11 @@ public:
if ((audio_sender_state_ == AudioState::IDLE) ||
(audio_sender_state_ == AudioState::READY_TO_RELEASE)) {
OnAudioSuspend();
+ } else {
+ /* If the local sink direction is used, we want to monitor
+ * if back channel is actually needed.
+ */
+ StartVbcCloseTimeout();
}
log::info("OUT: audio_receiver_state_: {}, audio_sender_state_: {}",
@@ -4468,6 +4476,7 @@ public:
if (group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) {
if (IsDirectionAvailableForCurrentConfiguration(
group, bluetooth::le_audio::types::kLeAudioDirectionSource)) {
+ StopSuspendTimeout();
StartReceivingAudio(active_group_id_);
} else {
log::warn(
@@ -4507,9 +4516,7 @@ public:
case AudioState::READY_TO_START:
case AudioState::READY_TO_RELEASE:
/* Stream is up just restore it */
- if (alarm_is_scheduled(suspend_timeout_)) {
- alarm_cancel(suspend_timeout_);
- }
+ StopSuspendTimeout();
ConfirmLocalAudioSinkStreamingRequest();
break;
case AudioState::RELEASING:
@@ -4604,9 +4611,7 @@ public:
return false;
}
- if (alarm_is_scheduled(suspend_timeout_)) {
- alarm_cancel(suspend_timeout_);
- }
+ StopSuspendTimeout();
/* Need to reconfigure stream. At this point pre_configuration_context_type shall be set */
diff --git a/system/bta/le_audio/client_parser.cc b/system/bta/le_audio/client_parser.cc
index f3b3b66925..9de6734bc7 100644
--- a/system/bta/le_audio/client_parser.cc
+++ b/system/bta/le_audio/client_parser.cc
@@ -33,7 +33,6 @@
#include "internal_include/bt_trace.h"
#include "le_audio_types.h"
#include "le_audio_utils.h"
-#include "os/log.h"
#include "stack/include/bt_types.h"
using bluetooth::le_audio::types::acs_ac_record;
diff --git a/system/bta/le_audio/codec_interface.cc b/system/bta/le_audio/codec_interface.cc
index b5c75c6e1c..637c77f5bf 100644
--- a/system/bta/le_audio/codec_interface.cc
+++ b/system/bta/le_audio/codec_interface.cc
@@ -25,8 +25,6 @@
#include <optional>
#include <vector>
-#include "os/log.h"
-
namespace bluetooth::le_audio {
struct CodecInterface::Impl {
diff --git a/system/bta/le_audio/codec_manager.cc b/system/bta/le_audio/codec_manager.cc
index fce821417d..117c3a2cec 100644
--- a/system/bta/le_audio/codec_manager.cc
+++ b/system/bta/le_audio/codec_manager.cc
@@ -31,7 +31,6 @@
#include "le_audio_set_configuration_provider.h"
#include "le_audio_utils.h"
#include "main/shim/entry.h"
-#include "os/log.h"
#include "osi/include/properties.h"
#include "stack/include/hcimsgs.h"
@@ -281,23 +280,47 @@ public:
return true;
}
- AudioSetConfigurations GetSupportedCodecConfigurations(
- const CodecManager::UnicastConfigurationRequirements& requirements) const {
+ std::unique_ptr<AudioSetConfiguration> GetLocalCodecConfigurations(
+ const CodecManager::UnicastConfigurationRequirements& requirements,
+ CodecManager::UnicastConfigurationProvider provider) const {
+ AudioSetConfigurations configs;
if (GetCodecLocation() == le_audio::types::CodecLocation::ADSP) {
log::verbose("Get offload config for the context type: {}",
(int)requirements.audio_context_type);
-
// TODO: Need to have a mechanism to switch to software session if offload
// doesn't support.
- return context_type_offload_config_map_.count(requirements.audio_context_type)
- ? context_type_offload_config_map_.at(requirements.audio_context_type)
- : AudioSetConfigurations();
+ configs = context_type_offload_config_map_.count(requirements.audio_context_type)
+ ? context_type_offload_config_map_.at(requirements.audio_context_type)
+ : AudioSetConfigurations();
+ } else {
+ log::verbose("Get software config for the context type: {}",
+ (int)requirements.audio_context_type);
+ configs = *AudioSetConfigurationProvider::Get()->GetConfigurations(
+ requirements.audio_context_type);
}
- log::verbose("Get software config for the context type: {}",
- (int)requirements.audio_context_type);
- return *AudioSetConfigurationProvider::Get()->GetConfigurations(
- requirements.audio_context_type);
+ if (configs.empty()) {
+ log::error("No valid configuration matching the requirements: {}", requirements);
+ PrintDebugState();
+ return nullptr;
+ }
+
+ // Remove the dual bidir SWB config if not supported
+ if (!IsDualBiDirSwbSupported()) {
+ configs.erase(std::remove_if(configs.begin(), configs.end(),
+ [](auto const& el) {
+ if (el->confs.source.empty()) {
+ return false;
+ }
+ return AudioSetConfigurationProvider::Get()
+ ->CheckConfigurationIsDualBiDirSwb(*el);
+ }),
+ configs.end());
+ }
+
+ // Note: For the software configuration provider, we use the provider matcher
+ // logic to match the proper configuration with group capabilities.
+ return provider(requirements, &configs);
}
void PrintDebugState() const {
@@ -318,6 +341,10 @@ public:
}
bool IsUsingCodecExtensibility() const {
+ if (GetCodecLocation() == types::CodecLocation::HOST) {
+ return false;
+ }
+
auto codec_ext_status =
osi_property_get_bool("bluetooth.core.le_audio.codec_extension_aidl.enabled", false) &&
com::android::bluetooth::flags::leaudio_multicodec_aidl_support();
@@ -334,37 +361,9 @@ public:
if (hal_config) {
return std::make_unique<AudioSetConfiguration>(*hal_config);
}
- log::debug(
- "No configuration received from AIDL, fall back to static "
- "configuration.");
+ log::debug("No configuration received from AIDL, fall back to static configuration.");
}
-
- auto configs = GetSupportedCodecConfigurations(requirements);
- if (configs.empty()) {
- log::error("No valid configuration matching the requirements: {}", requirements);
- PrintDebugState();
- return nullptr;
- }
-
- // Remove the dual bidir SWB config if not supported
- if (!IsDualBiDirSwbSupported()) {
- configs.erase(std::remove_if(configs.begin(), configs.end(),
- [](auto const& el) {
- if (el->confs.source.empty()) {
- return false;
- }
- return AudioSetConfigurationProvider::Get()
- ->CheckConfigurationIsDualBiDirSwb(*el);
- }),
- configs.end());
- }
-
- // Note: For the only supported right now legacy software configuration
- // provider, we use the device group logic to match the proper
- // configuration with group capabilities. Note that this path only
- // supports the LC3 codec format. For the multicodec support we should
- // rely on the configuration matcher behind the AIDL interface.
- return provider(requirements, &configs);
+ return GetLocalCodecConfigurations(requirements, provider);
}
bool CheckCodecConfigIsBiDirSwb(const AudioSetConfiguration& config) {
diff --git a/system/bta/le_audio/codec_manager_test.cc b/system/bta/le_audio/codec_manager_test.cc
index d72d587880..5770fdbea4 100644
--- a/system/bta/le_audio/codec_manager_test.cc
+++ b/system/bta/le_audio/codec_manager_test.cc
@@ -265,6 +265,8 @@ void set_mock_offload_capabilities(const std::vector<AudioSetConfiguration>& cap
}
static constexpr char kPropLeAudioOffloadSupported[] = "ro.bluetooth.leaudio_offload.supported";
+static constexpr char kPropLeAudioCodecExtensibility[] =
+ "bluetooth.core.le_audio.codec_extension_aidl.enabled";
static constexpr char kPropLeAudioOffloadDisabled[] = "persist.bluetooth.leaudio_offload.disabled";
static constexpr char kPropLeAudioBidirSwbSupported[] =
"bluetooth.leaudio.dual_bidirection_swb.supported";
@@ -823,6 +825,10 @@ public:
// Allow for bidir SWB configurations
osi_property_set_bool(kPropLeAudioBidirSwbSupported, true);
+ // Codec extensibility disabled by default
+ com::android::bluetooth::flags::provider_->leaudio_multicodec_aidl_support(false);
+ osi_property_set_bool(kPropLeAudioCodecExtensibility, false);
+
CodecManagerTestBase::SetUp();
}
};
@@ -837,6 +843,10 @@ public:
// Do not allow for bidir SWB configurations
osi_property_set_bool(kPropLeAudioBidirSwbSupported, false);
+ // Codec extensibility disabled by default
+ com::android::bluetooth::flags::provider_->leaudio_multicodec_aidl_support(false);
+ osi_property_set_bool(kPropLeAudioCodecExtensibility, false);
+
CodecManagerTestBase::SetUp();
}
};
@@ -1295,4 +1305,28 @@ TEST_F(CodecManagerTestHost, test_dont_update_broadcast_offloader) {
ASSERT_FALSE(was_called);
}
+TEST_F(CodecManagerTestHost, test_dont_call_hal_for_config) {
+ com::android::bluetooth::flags::provider_->leaudio_multicodec_aidl_support(true);
+ osi_property_set_bool(kPropLeAudioCodecExtensibility, true);
+
+ // Set the offloader capabilities
+ std::vector<AudioSetConfiguration> offload_capabilities;
+ set_mock_offload_capabilities(offload_capabilities);
+
+ const std::vector<bluetooth::le_audio::btle_audio_codec_config_t> offloading_preference = {};
+ codec_manager->Start(offloading_preference);
+ codec_manager->UpdateActiveUnicastAudioHalClient(mock_le_audio_source_hal_client_,
+ mock_le_audio_sink_hal_client_, true);
+
+ EXPECT_CALL(*mock_le_audio_source_hal_client_, GetUnicastConfig(_)).Times(0);
+ codec_manager->GetCodecConfig(
+ {.audio_context_type = types::LeAudioContextType::MEDIA},
+ [&](const CodecManager::UnicastConfigurationRequirements& /*requirements*/,
+ const set_configurations::AudioSetConfigurations* /*confs*/)
+ -> std::unique_ptr<set_configurations::AudioSetConfiguration> {
+ // In this case the chosen configuration doesn't matter - select none
+ return nullptr;
+ });
+}
+
} // namespace bluetooth::le_audio
diff --git a/system/bta/le_audio/content_control_id_keeper.cc b/system/bta/le_audio/content_control_id_keeper.cc
index cfda2dedc2..f4ca933f06 100644
--- a/system/bta/le_audio/content_control_id_keeper.cc
+++ b/system/bta/le_audio/content_control_id_keeper.cc
@@ -24,7 +24,6 @@
#include "common/strings.h"
#include "le_audio_types.h"
-#include "os/log.h"
namespace {
diff --git a/system/bta/le_audio/devices.h b/system/bta/le_audio/devices.h
index 1f972aae85..0707bae4b4 100644
--- a/system/bta/le_audio/devices.h
+++ b/system/bta/le_audio/devices.h
@@ -26,7 +26,6 @@
#include "gatt_api.h"
#include "gmap_client.h"
#include "le_audio_types.h"
-#include "os/log.h"
#include "osi/include/alarm.h"
#include "raw_address.h"
diff --git a/system/bta/le_audio/devices_test.cc b/system/bta/le_audio/devices_test.cc
index 1ad0684ce6..11480961b8 100644
--- a/system/bta/le_audio/devices_test.cc
+++ b/system/bta/le_audio/devices_test.cc
@@ -32,7 +32,6 @@
#include "le_audio_types.h"
#include "mock_codec_manager.h"
#include "mock_csis_client.h"
-#include "os/log.h"
#include "stack/btm/btm_int_types.h"
#include "test/mock/mock_main_shim_entry.h"
diff --git a/system/bta/le_audio/le_audio_client_test.cc b/system/bta/le_audio/le_audio_client_test.cc
index 333f4e8573..05a26249ac 100644
--- a/system/bta/le_audio/le_audio_client_test.cc
+++ b/system/bta/le_audio/le_audio_client_test.cc
@@ -1442,6 +1442,7 @@ protected:
void SetUp() override {
__android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
init_message_loop_thread();
+ reset_mock_function_count_map();
ON_CALL(controller_, SupportsBleConnectedIsochronousStreamCentral).WillByDefault(Return(true));
ON_CALL(controller_, SupportsBleConnectedIsochronousStreamPeripheral)
.WillByDefault(Return(true));
@@ -9914,6 +9915,83 @@ TEST_F(UnicastTest, MicrophoneAttachToCurrentMediaScenario) {
Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
}
+TEST_F(UnicastTest, SwitchBetweenMicrophoneAndSoundEffectScenario) {
+ const RawAddress test_address0 = GetTestAddress(0);
+ int group_id = bluetooth::groups::kGroupUnknown;
+
+ /* Scenario:
+ * 1. User starts Recording - this creates bidiretional CISes
+ * 2. User stops recording - this starts suspend timeout (500ms)
+ * 3. Since user touch the screen it generates touch tone - this shall reuse existing CISes when
+ * it happens 500ms before stop
+ */
+ SetSampleDatabaseEarbudsValid(1, test_address0, codec_spec_conf::kLeAudioLocationStereo,
+ codec_spec_conf::kLeAudioLocationFrontLeft, default_channel_cnt,
+ default_channel_cnt, 0x0024, false /*add_csis*/, true /*add_cas*/,
+ true /*add_pacs*/, default_ase_cnt /*add_ascs_cnt*/, 1 /*set_size*/,
+ 0 /*rank*/);
+ EXPECT_CALL(mock_audio_hal_client_callbacks_,
+ OnConnectionState(ConnectionState::CONNECTED, test_address0))
+ .Times(1);
+ EXPECT_CALL(mock_audio_hal_client_callbacks_,
+ OnGroupNodeStatus(test_address0, _, GroupNodeStatus::ADDED))
+ .WillOnce(DoAll(SaveArg<1>(&group_id)));
+
+ ConnectLeAudio(test_address0);
+ ASSERT_NE(group_id, bluetooth::groups::kGroupUnknown);
+
+ // Audio sessions are started only when device gets active
+ EXPECT_CALL(*mock_le_audio_source_hal_client_, Start(_, _, _)).Times(1);
+ EXPECT_CALL(*mock_le_audio_sink_hal_client_, Start(_, _, _)).Times(1);
+ LeAudioClient::Get()->GroupSetActive(group_id);
+ SyncOnMainLoop();
+
+ // When the local audio source resumes we have no knowledge of recording
+ EXPECT_CALL(mock_state_machine_,
+ StartStream(_, bluetooth::le_audio::types::LeAudioContextType::LIVE, _, _))
+ .Times(1);
+
+ log::info("Start Microphone recording - bidirectional CISes are expected");
+ UpdateLocalSinkMetadata(AUDIO_SOURCE_MIC);
+ LocalAudioSinkResume();
+
+ ASSERT_EQ(0, get_func_call_count("alarm_set_on_mloop"));
+ SyncOnMainLoop();
+
+ Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_);
+ Mock::VerifyAndClearExpectations(mock_le_audio_source_hal_client_);
+ Mock::VerifyAndClearExpectations(&mock_state_machine_);
+
+ // Verify Data transfer on one audio source cis
+ uint8_t cis_count_out = 0;
+ uint8_t cis_count_in = 1;
+ TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 60);
+
+ log::info("Suspend microphone recording - suspend timeout is not fired");
+ LocalAudioSinkSuspend();
+ SyncOnMainLoop();
+
+ // VBC and Suspend
+ ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
+ ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
+
+ log::info("Resume local source with touch tone - expect suspend timeout to be canceled");
+
+ UpdateLocalSourceMetadata(AUDIO_USAGE_ASSISTANCE_SONIFICATION, AUDIO_CONTENT_TYPE_SONIFICATION);
+ LocalAudioSourceResume();
+ SyncOnMainLoop();
+
+ ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
+
+ auto group = streaming_groups.at(group_id);
+ group->PrintDebugState();
+
+ // Verify Data transfer on one audio source and sink cis
+ cis_count_out = 1;
+ cis_count_in = 0;
+ TestAudioDataTransfer(group_id, cis_count_out, cis_count_in, 1920, 60);
+}
+
/* When a certain context is unavailable and not supported we should stream
* as UNSPECIFIED for the backwards compatibility.
* Since UNSPECIFIED is available, put the UNSPECIFIED into the metadata instead
diff --git a/system/bta/le_audio/le_audio_health_status.cc b/system/bta/le_audio/le_audio_health_status.cc
index 3b349e8179..5a2c2feb92 100644
--- a/system/bta/le_audio/le_audio_health_status.cc
+++ b/system/bta/le_audio/le_audio_health_status.cc
@@ -23,7 +23,6 @@
#include "bta/include/bta_groups.h"
#include "common/strings.h"
#include "main/shim/metrics_api.h"
-#include "os/log.h"
#include "osi/include/properties.h"
using bluetooth::common::ToString;
diff --git a/system/bta/le_audio/le_audio_log_history.cc b/system/bta/le_audio/le_audio_log_history.cc
index 0022d7b7da..22fd939994 100644
--- a/system/bta/le_audio/le_audio_log_history.cc
+++ b/system/bta/le_audio/le_audio_log_history.cc
@@ -25,7 +25,7 @@
#include "common/circular_buffer.h"
#include "common/strings.h"
#include "main/shim/dumpsys.h"
-#include "os/log.h"
+#include "os/logging/log_adapter.h"
#include "osi/include/osi.h"
#include "osi/include/properties.h"
diff --git a/system/bta/le_audio/le_audio_set_configuration_provider_json.cc b/system/bta/le_audio/le_audio_set_configuration_provider_json.cc
index 169943323c..3b8643152d 100644
--- a/system/bta/le_audio/le_audio_set_configuration_provider_json.cc
+++ b/system/bta/le_audio/le_audio_set_configuration_provider_json.cc
@@ -29,7 +29,6 @@
#include "flatbuffers/util.h"
#include "le_audio/le_audio_types.h"
#include "le_audio_set_configuration_provider.h"
-#include "os/log.h"
#include "osi/include/osi.h"
#include "osi/include/properties.h"
diff --git a/system/bta/le_audio/le_audio_utils.cc b/system/bta/le_audio/le_audio_utils.cc
index 2e29fd1e03..719d017607 100644
--- a/system/bta/le_audio/le_audio_utils.cc
+++ b/system/bta/le_audio/le_audio_utils.cc
@@ -20,7 +20,6 @@
#include "common/strings.h"
#include "le_audio_types.h"
-#include "os/log.h"
using bluetooth::common::ToString;
using bluetooth::le_audio::types::AudioContexts;
diff --git a/system/bta/le_audio/storage_helper.cc b/system/bta/le_audio/storage_helper.cc
index b9f24233c3..916c8249b1 100644
--- a/system/bta/le_audio/storage_helper.cc
+++ b/system/bta/le_audio/storage_helper.cc
@@ -23,7 +23,6 @@
#include "client_parser.h"
#include "common/strings.h"
#include "le_audio_types.h"
-#include "os/log.h"
#include "stack/include/bt_types.h"
// TODO(b/369381361) Enfore -Wmissing-prototypes
diff --git a/system/bta/ras/ras_utils.cc b/system/bta/ras/ras_utils.cc
index d27a6bf697..2a9b3b9c88 100644
--- a/system/bta/ras/ras_utils.cc
+++ b/system/bta/ras/ras_utils.cc
@@ -21,7 +21,6 @@
#include "bta/include/bta_gatt_api.h"
#include "bta/include/bta_ras_api.h"
#include "bta/ras/ras_types.h"
-#include "os/log.h"
#include "stack/include/bt_types.h"
#include "stack/include/btm_ble_addr.h"
#include "stack/include/gap_api.h"
diff --git a/system/bta/sys/bta_sys_main.cc b/system/bta/sys/bta_sys_main.cc
index 4e5ad74d52..524f750ff7 100644
--- a/system/bta/sys/bta_sys_main.cc
+++ b/system/bta/sys/bta_sys_main.cc
@@ -33,7 +33,6 @@
#include "bta/sys/bta_sys_int.h"
#include "include/hardware/bluetooth.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/alarm.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/bta/test/common/fake_osi.h b/system/bta/test/common/fake_osi.h
index 9eceafaa91..1a9456d628 100644
--- a/system/bta/test/common/fake_osi.h
+++ b/system/bta/test/common/fake_osi.h
@@ -21,6 +21,7 @@
#include "osi/include/alarm.h"
struct fake_osi_alarm_set_on_mloop {
+ alarm_t* alarm;
uint64_t interval_ms{0};
alarm_callback_t cb{};
void* data{nullptr};
diff --git a/system/bta/vc/device.cc b/system/bta/vc/device.cc
index ec2088981e..f4f016f2d9 100644
--- a/system/bta/vc/device.cc
+++ b/system/bta/vc/device.cc
@@ -25,7 +25,6 @@
#include "bta/include/bta_gatt_queue.h"
#include "bta/vc/devices.h"
#include "internal_include/bt_trace.h"
-#include "os/log.h"
#include "os/logging/log_adapter.h"
#include "stack/btm/btm_sec.h"
#include "stack/include/bt_types.h"
diff --git a/system/bta/vc/vc.cc b/system/bta/vc/vc.cc
index 6a449c74c3..2c415a59c0 100644
--- a/system/bta/vc/vc.cc
+++ b/system/bta/vc/vc.cc
@@ -33,7 +33,6 @@
#include "bta/le_audio/le_audio_types.h"
#include "bta/vc/devices.h"
#include "internal_include/bt_trace.h"
-#include "os/log.h"
#include "osi/include/osi.h"
#include "stack/btm/btm_sec.h"
#include "stack/include/bt_types.h"
diff --git a/system/btcore/src/module.cc b/system/btcore/src/module.cc
index 3f809d4d5d..ec34b32636 100644
--- a/system/btcore/src/module.cc
+++ b/system/btcore/src/module.cc
@@ -28,7 +28,6 @@
#include <unordered_map>
#include "common/message_loop_thread.h"
-#include "os/log.h"
using bluetooth::common::MessageLoopThread;
using namespace bluetooth;
diff --git a/system/btcore/src/osi_module.cc b/system/btcore/src/osi_module.cc
index 22d8f05398..638748fe03 100644
--- a/system/btcore/src/osi_module.cc
+++ b/system/btcore/src/osi_module.cc
@@ -21,7 +21,6 @@
#include "btcore/include/osi_module.h"
#include "btcore/include/module.h"
-#include "os/log.h"
#include "osi/include/alarm.h"
#include "osi/include/future.h"
#include "osi/include/osi.h"
diff --git a/system/btif/Android.bp b/system/btif/Android.bp
index 9b22ee4784..2d3d40e3fd 100644
--- a/system/btif/Android.bp
+++ b/system/btif/Android.bp
@@ -597,8 +597,6 @@ cc_test {
"libbt-platform-protos-lite",
"libbt-sbc-decoder",
"libbt-sbc-encoder",
- "libbt-stack",
- "libbt-stack-core",
"libbtdevice",
"libbtif",
"libbtif-core",
diff --git a/system/btif/avrcp/avrcp_service.cc b/system/btif/avrcp/avrcp_service.cc
index 577628eb2b..ce1b1ce577 100644
--- a/system/btif/avrcp/avrcp_service.cc
+++ b/system/btif/avrcp/avrcp_service.cc
@@ -32,6 +32,7 @@
#include "btif/include/btif_av.h"
#include "btif/include/btif_common.h"
#include "osi/include/osi.h"
+#include "profile/avrcp/avrcp_config.h"
#include "profile/avrcp/device.h"
#include "stack/include/a2dp_api.h"
#include "stack/include/bt_hdr.h"
@@ -100,7 +101,7 @@ public:
return AVRC_Open(p_handle, p_ccb, bd_addr);
}
- uint16_t OpenBrowse(uint8_t handle, uint8_t conn_role) override {
+ uint16_t OpenBrowse(uint8_t handle, tAVCT_ROLE conn_role) override {
return AVRC_OpenBrowse(handle, conn_role);
}
diff --git a/system/btif/co/bta_pan_co.cc b/system/btif/co/bta_pan_co.cc
index bdc0ac397b..db84d8bd34 100644
--- a/system/btif/co/bta_pan_co.cc
+++ b/system/btif/co/bta_pan_co.cc
@@ -36,7 +36,6 @@
#include "btif_pan_internal.h"
#include "btif_sock_thread.h"
#include "btif_util.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "pan_api.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/btif/include/btif_common.h b/system/btif/include/btif_common.h
index 64433579f0..109dd49893 100644
--- a/system/btif/include/btif_common.h
+++ b/system/btif/include/btif_common.h
@@ -30,7 +30,6 @@
#include "abstract_message_loop.h"
#include "bta/include/bta_api.h"
-#include "os/log.h"
#include "osi/include/osi.h"
#include "stack/include/bt_hdr.h"
#include "types/raw_address.h"
diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc
index f246ca1be8..c4bb371e80 100644
--- a/system/btif/src/bluetooth.cc
+++ b/system/btif/src/bluetooth.cc
@@ -100,8 +100,9 @@
#include "osi/include/wakelock.h"
#include "stack/btm/btm_dev.h"
#include "stack/btm/btm_sco_hfp_hal.h"
-#include "stack/gatt/connection_manager.h"
+#include "stack/connection_manager/connection_manager.h"
#include "stack/include/a2dp_api.h"
+#include "stack/include/avct_api.h"
#include "stack/include/avdt_api.h"
#include "stack/include/btm_client_interface.h"
#include "stack/include/btm_status.h"
@@ -886,6 +887,7 @@ static void dump(int fd, const char** arguments) {
VolumeControl::DebugDump(fd);
connection_manager::dump(fd);
bluetooth::bqr::DebugDump(fd);
+ AVCT_Dumpsys(fd);
PAN_Dumpsys(fd);
DumpsysHid(fd);
DumpsysBtaDm(fd);
diff --git a/system/btif/src/btif_a2dp.cc b/system/btif/src/btif_a2dp.cc
index f8036bf8c8..01127c3a68 100644
--- a/system/btif/src/btif_a2dp.cc
+++ b/system/btif/src/btif_a2dp.cc
@@ -130,6 +130,8 @@ void btif_a2dp_on_offload_started(const RawAddress& peer_addr, tBTA_AV_STATUS st
switch (status) {
case BTA_AV_SUCCESS:
+ // Call required to update the session state for metrics.
+ btif_a2dp_source_start_audio_req();
ack = BluetoothAudioStatus::SUCCESS;
break;
case BTA_AV_FAIL_RESOURCES:
diff --git a/system/btif/src/btif_a2dp_source.cc b/system/btif/src/btif_a2dp_source.cc
index 61dedb5bf3..ae296a4249 100644
--- a/system/btif/src/btif_a2dp_source.cc
+++ b/system/btif/src/btif_a2dp_source.cc
@@ -55,6 +55,7 @@
#include "stack/include/bt_hdr.h"
#include "stack/include/btm_client_interface.h"
#include "stack/include/btm_status.h"
+#include "stack/include/main_thread.h"
#include "types/raw_address.h"
using bluetooth::audio::a2dp::BluetoothAudioStatus;
@@ -227,9 +228,14 @@ private:
BtifA2dpSource::RunState state_;
};
+/// Source worker thread created to run the CPU heavy encoder calls.
+/// Exactly three functions are executed on this thread:
+/// - btif_a2dp_source_audio_handle_timer
+/// - btif_a2dp_source_read_callback
+/// - btif_a2dp_source_enqueue_callback
static bluetooth::common::MessageLoopThread btif_a2dp_source_thread("bt_a2dp_source_worker_thread");
-static BtifA2dpSource btif_a2dp_source_cb;
+static BtifA2dpSource btif_a2dp_source_cb;
static uint8_t btif_a2dp_source_dynamic_audio_buffer_size = MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ;
static void btif_a2dp_source_init_delayed(void);
@@ -313,12 +319,19 @@ static void btif_a2dp_source_accumulate_stats(BtifMediaStats* src, BtifMediaStat
src->Reset();
}
+/// Select the thread to run a2dp source actions on (a2dp encoder excluded).
+static bluetooth::common::MessageLoopThread* local_thread() {
+ return com::android::bluetooth::flags::a2dp_source_threading_fix() ? get_main_thread()
+ : &btif_a2dp_source_thread;
+}
+
bool btif_a2dp_source_init(void) {
log::info("");
// Start A2DP Source media task
btif_a2dp_source_thread.StartUp();
- btif_a2dp_source_thread.DoInThread(FROM_HERE, base::BindOnce(&btif_a2dp_source_init_delayed));
+
+ local_thread()->DoInThread(FROM_HERE, base::BindOnce(&btif_a2dp_source_init_delayed));
return true;
}
@@ -384,8 +397,7 @@ static void btif_a2dp_source_init_delayed(void) {
// the provider needs to be initialized earlier in order to ensure
// get_a2dp_configuration and parse_a2dp_configuration can be
// invoked before the stream is started.
- bluetooth::audio::a2dp::init(&btif_a2dp_source_thread, &a2dp_audio_port,
- btif_av_is_a2dp_offload_enabled());
+ bluetooth::audio::a2dp::init(local_thread(), &a2dp_audio_port, btif_av_is_a2dp_offload_enabled());
}
static bool btif_a2dp_source_startup(void) {
@@ -401,7 +413,7 @@ static bool btif_a2dp_source_startup(void) {
btif_a2dp_source_cb.tx_audio_queue = fixed_queue_new(SIZE_MAX);
// Schedule the rest of the operations
- btif_a2dp_source_thread.DoInThread(FROM_HERE, base::BindOnce(&btif_a2dp_source_startup_delayed));
+ local_thread()->DoInThread(FROM_HERE, base::BindOnce(&btif_a2dp_source_startup_delayed));
return true;
}
@@ -413,7 +425,7 @@ static void btif_a2dp_source_startup_delayed() {
log::fatal("unable to enable real time scheduling");
#endif
}
- if (!bluetooth::audio::a2dp::init(&btif_a2dp_source_thread, &a2dp_audio_port,
+ if (!bluetooth::audio::a2dp::init(local_thread(), &a2dp_audio_port,
btif_av_is_a2dp_offload_enabled())) {
log::warn("Failed to setup the bluetooth audio HAL");
}
@@ -426,7 +438,7 @@ bool btif_a2dp_source_start_session(const RawAddress& peer_address,
btif_a2dp_source_audio_tx_flush_req();
- if (btif_a2dp_source_thread.DoInThread(
+ if (local_thread()->DoInThread(
FROM_HERE, base::BindOnce(&btif_a2dp_source_start_session_delayed, peer_address,
std::move(peer_ready_promise)))) {
return true;
@@ -491,8 +503,8 @@ bool btif_a2dp_source_restart_session(const RawAddress& old_peer_address,
bool btif_a2dp_source_end_session(const RawAddress& peer_address) {
log::info("peer_address={} state={}", peer_address, btif_a2dp_source_cb.StateStr());
- btif_a2dp_source_thread.DoInThread(
- FROM_HERE, base::BindOnce(&btif_a2dp_source_end_session_delayed, peer_address));
+ local_thread()->DoInThread(FROM_HERE,
+ base::BindOnce(&btif_a2dp_source_end_session_delayed, peer_address));
btif_a2dp_source_cleanup_codec();
return true;
}
@@ -518,7 +530,7 @@ static void btif_a2dp_source_end_session_delayed(const RawAddress& peer_address)
void btif_a2dp_source_allow_low_latency_audio(bool allowed) {
log::info("allowed={}", allowed);
- btif_a2dp_source_thread.DoInThread(
+ local_thread()->DoInThread(
FROM_HERE,
base::BindOnce(bluetooth::audio::a2dp::set_audio_low_latency_mode_allowed, allowed));
}
@@ -534,9 +546,8 @@ void btif_a2dp_source_shutdown(std::promise<void> shutdown_complete_promise) {
/* Make sure no channels are restarted while shutting down */
btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateShuttingDown);
- btif_a2dp_source_thread.DoInThread(
- FROM_HERE,
- base::BindOnce(&btif_a2dp_source_shutdown_delayed, std::move(shutdown_complete_promise)));
+ local_thread()->DoInThread(FROM_HERE, base::BindOnce(&btif_a2dp_source_shutdown_delayed,
+ std::move(shutdown_complete_promise)));
}
static void btif_a2dp_source_shutdown_delayed(std::promise<void> shutdown_complete_promise) {
@@ -614,8 +625,9 @@ static void btif_a2dp_source_setup_codec(const RawAddress& peer_address) {
log::error("Cannot stream audio: cannot set active peer to {}", peer_address);
return;
}
- btif_a2dp_source_cb.encoder_interface = bta_av_co_get_encoder_interface(peer_address);
- if (btif_a2dp_source_cb.encoder_interface == nullptr) {
+
+ const tA2DP_ENCODER_INTERFACE* encoder_interface = bta_av_co_get_encoder_interface(peer_address);
+ if (encoder_interface == nullptr) {
log::error("Cannot stream audio: no source encoder interface");
return;
}
@@ -626,11 +638,11 @@ static void btif_a2dp_source_setup_codec(const RawAddress& peer_address) {
return;
}
- btif_a2dp_source_cb.encoder_interface->encoder_init(&peer_params, a2dp_codec_config,
- btif_a2dp_source_read_callback,
- btif_a2dp_source_enqueue_callback);
+ encoder_interface->encoder_init(&peer_params, a2dp_codec_config, btif_a2dp_source_read_callback,
+ btif_a2dp_source_enqueue_callback);
// Save a local copy of the encoder_interval_ms
+ btif_a2dp_source_cb.encoder_interface = encoder_interface;
btif_a2dp_source_cb.encoder_interval_ms =
btif_a2dp_source_cb.encoder_interface->get_encoder_interval_ms();
@@ -645,8 +657,7 @@ static void btif_a2dp_source_cleanup_codec() {
log::info("state={}", btif_a2dp_source_cb.StateStr());
// Must stop media task first before cleaning up the encoder
btif_a2dp_source_stop_audio_req();
- btif_a2dp_source_thread.DoInThread(FROM_HERE,
- base::BindOnce(&btif_a2dp_source_cleanup_codec_delayed));
+ local_thread()->DoInThread(FROM_HERE, base::BindOnce(&btif_a2dp_source_cleanup_codec_delayed));
}
static void btif_a2dp_source_cleanup_codec_delayed() {
@@ -660,15 +671,13 @@ static void btif_a2dp_source_cleanup_codec_delayed() {
void btif_a2dp_source_start_audio_req(void) {
log::info("state={}", btif_a2dp_source_cb.StateStr());
- btif_a2dp_source_thread.DoInThread(FROM_HERE,
- base::BindOnce(&btif_a2dp_source_audio_tx_start_event));
+ local_thread()->DoInThread(FROM_HERE, base::BindOnce(&btif_a2dp_source_audio_tx_start_event));
}
void btif_a2dp_source_stop_audio_req(void) {
log::info("state={}", btif_a2dp_source_cb.StateStr());
- btif_a2dp_source_thread.DoInThread(FROM_HERE,
- base::BindOnce(&btif_a2dp_source_audio_tx_stop_event));
+ local_thread()->DoInThread(FROM_HERE, base::BindOnce(&btif_a2dp_source_audio_tx_stop_event));
}
void btif_a2dp_source_encoder_user_config_update_req(
@@ -677,7 +686,8 @@ void btif_a2dp_source_encoder_user_config_update_req(
std::promise<void> peer_ready_promise) {
log::info("peer_address={} state={} {} codec_preference(s)", peer_address,
btif_a2dp_source_cb.StateStr(), codec_user_preferences.size());
- if (!btif_a2dp_source_thread.DoInThread(
+
+ if (!local_thread()->DoInThread(
FROM_HERE,
base::BindOnce(&btif_a2dp_source_encoder_user_config_update_event, peer_address,
codec_user_preferences, std::move(peer_ready_promise)))) {
@@ -723,9 +733,8 @@ static void btif_a2dp_source_encoder_user_config_update_event(
void btif_a2dp_source_feeding_update_req(const btav_a2dp_codec_config_t& codec_audio_config) {
log::info("state={}", btif_a2dp_source_cb.StateStr());
- btif_a2dp_source_thread.DoInThread(
- FROM_HERE,
- base::BindOnce(&btif_a2dp_source_audio_feeding_update_event, codec_audio_config));
+ local_thread()->DoInThread(FROM_HERE, base::BindOnce(&btif_a2dp_source_audio_feeding_update_event,
+ codec_audio_config));
}
static void btif_a2dp_source_audio_feeding_update_event(
@@ -761,7 +770,6 @@ void btif_a2dp_source_on_stopped(tBTA_AV_SUSPEND* p_av_suspend) {
}
} else {
bluetooth::audio::a2dp::ack_stream_suspended(BluetoothAudioStatus::SUCCESS);
- return;
}
if (btif_a2dp_source_cb.State() == BtifA2dpSource::kStateOff) {
@@ -797,7 +805,6 @@ void btif_a2dp_source_on_suspended(tBTA_AV_SUSPEND* p_av_suspend) {
}
} else if (btif_av_is_a2dp_offload_running()) {
bluetooth::audio::a2dp::ack_stream_suspended(BluetoothAudioStatus::SUCCESS);
- return;
}
// ensure tx frames are immediately suspended
@@ -819,60 +826,54 @@ static void btif_a2dp_source_audio_tx_start_event(void) {
log::info("streaming {} state={}", btif_a2dp_source_is_streaming(),
btif_a2dp_source_cb.StateStr());
+ btif_a2dp_source_cb.stats.Reset();
+ btif_a2dp_source_cb.stats.session_start_us = bluetooth::common::time_get_os_boottime_us();
+ btif_a2dp_source_cb.stats.session_end_us = 0;
+
+ A2dpCodecConfig* codec_config = bta_av_get_a2dp_current_codec();
+ if (codec_config != nullptr) {
+ btif_a2dp_source_cb.stats.codec_index = codec_config->codecIndex();
+ }
+
if (btif_av_is_a2dp_offload_running()) {
return;
}
- /* Reset the media feeding state */
log::assert_that(btif_a2dp_source_cb.encoder_interface != nullptr,
"assert failed: btif_a2dp_source_cb.encoder_interface != nullptr");
- btif_a2dp_source_cb.encoder_interface->feeding_reset();
- log::verbose("starting timer {} ms",
+ log::verbose("starting media encoder timer with interval {}ms",
btif_a2dp_source_cb.encoder_interface->get_encoder_interval_ms());
- /* audio engine starting, reset tx suspended flag */
- btif_a2dp_source_cb.tx_flush = false;
-
wakelock_acquire();
+ btif_a2dp_source_cb.encoder_interface->feeding_reset();
+ btif_a2dp_source_cb.tx_flush = false;
+ btif_a2dp_source_cb.sw_audio_is_encoding = true;
btif_a2dp_source_cb.media_alarm.SchedulePeriodic(
btif_a2dp_source_thread.GetWeakPtr(), FROM_HERE,
base::BindRepeating(&btif_a2dp_source_audio_handle_timer),
std::chrono::milliseconds(
btif_a2dp_source_cb.encoder_interface->get_encoder_interval_ms()));
- btif_a2dp_source_cb.sw_audio_is_encoding = true;
-
- btif_a2dp_source_cb.stats.Reset();
- // Assign session_start_us to 1 when
- // bluetooth::common::time_get_os_boottime_us() is 0 to indicate
- // btif_a2dp_source_start_audio_req() has been called
- btif_a2dp_source_cb.stats.session_start_us = bluetooth::common::time_get_os_boottime_us();
- if (btif_a2dp_source_cb.stats.session_start_us == 0) {
- btif_a2dp_source_cb.stats.session_start_us = 1;
- }
- btif_a2dp_source_cb.stats.session_end_us = 0;
- A2dpCodecConfig* codec_config = bta_av_get_a2dp_current_codec();
- if (codec_config != nullptr) {
- btif_a2dp_source_cb.stats.codec_index = codec_config->codecIndex();
- }
}
static void btif_a2dp_source_audio_tx_stop_event(void) {
log::info("streaming {} state={}", btif_a2dp_source_is_streaming(),
btif_a2dp_source_cb.StateStr());
+ btif_a2dp_source_cb.stats.session_end_us = bluetooth::common::time_get_os_boottime_us();
+
+ btif_a2dp_source_update_metrics();
+ btif_a2dp_source_accumulate_stats(&btif_a2dp_source_cb.stats,
+ &btif_a2dp_source_cb.accumulated_stats);
+
if (btif_av_is_a2dp_offload_running()) {
return;
}
+
if (!btif_a2dp_source_is_streaming()) {
return;
}
- btif_a2dp_source_cb.stats.session_end_us = bluetooth::common::time_get_os_boottime_us();
- btif_a2dp_source_update_metrics();
- btif_a2dp_source_accumulate_stats(&btif_a2dp_source_cb.stats,
- &btif_a2dp_source_cb.accumulated_stats);
-
/* Drain data still left in the queue */
static constexpr size_t AUDIO_STREAM_OUTPUT_BUFFER_SZ = 28 * 512;
uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2];
@@ -893,39 +894,48 @@ static void btif_a2dp_source_audio_tx_stop_event(void) {
}
}
+/// Periodic task responsible for encoding the audio stream and forwarding
+/// to the remote device. It will read PCM samples from the HAL provided FMQ,
+/// encode them into audio frames. Runs on the source worker thread.
+///
+/// The timer driving the periodic task is cancelled before any state cleanup
+/// when the stream is ended.
static void btif_a2dp_source_audio_handle_timer(void) {
- if (btif_av_is_a2dp_offload_running()) {
- return;
- }
-
uint64_t timestamp_us = bluetooth::common::time_get_audio_server_tick_us();
uint64_t stats_timestamp_us = bluetooth::common::time_get_os_boottime_us();
log_tstamps_us("A2DP Source tx scheduling timer", timestamp_us);
- if (!btif_a2dp_source_is_streaming()) {
- log::error("ERROR Media task Scheduled after Suspend");
- return;
- }
log::assert_that(btif_a2dp_source_cb.encoder_interface != nullptr,
"assert failed: btif_a2dp_source_cb.encoder_interface != nullptr");
+
size_t transmit_queue_length = fixed_queue_length(btif_a2dp_source_cb.tx_audio_queue);
+
#ifdef __ANDROID__
ATRACE_INT("btif TX queue", transmit_queue_length);
#endif
+
if (btif_a2dp_source_cb.encoder_interface->set_transmit_queue_length != nullptr) {
btif_a2dp_source_cb.encoder_interface->set_transmit_queue_length(transmit_queue_length);
}
+
btif_a2dp_source_cb.encoder_interface->send_frames(timestamp_us);
+
bta_av_ci_src_data_ready(BTA_AV_CHNL_AUDIO);
update_scheduling_stats(&btif_a2dp_source_cb.stats.tx_queue_enqueue_stats, stats_timestamp_us,
btif_a2dp_source_cb.encoder_interval_ms * 1000);
}
+/// Callback invoked by the encoder for reading PCM audio data from the
+/// Bluetooth Audio HAL. Runs on the source worker thread.
static uint32_t btif_a2dp_source_read_callback(uint8_t* p_buf, uint32_t len) {
+ if (!btif_a2dp_source_cb.sw_audio_is_encoding) {
+ return 0;
+ }
+
uint32_t bytes_read = bluetooth::audio::a2dp::read(p_buf, len);
- if (btif_a2dp_source_cb.sw_audio_is_encoding && bytes_read < len) {
+ if (bytes_read < len) {
log::warn("UNDERFLOW: ONLY READ {} BYTES OUT OF {}", bytes_read, len);
btif_a2dp_source_cb.stats.media_read_total_underflow_bytes += (len - bytes_read);
btif_a2dp_source_cb.stats.media_read_total_underflow_count++;
@@ -938,17 +948,13 @@ static uint32_t btif_a2dp_source_read_callback(uint8_t* p_buf, uint32_t len) {
return bytes_read;
}
+/// Callback invoked by the encoder for sending encoded audio frames to the
+/// remote Bluetooth device. Runs on the source worker thread.
static bool btif_a2dp_source_enqueue_callback(BT_HDR* p_buf, size_t frames_n,
uint32_t /*bytes_read*/) {
uint64_t now_us = bluetooth::common::time_get_os_boottime_us();
- /* Check if timer was stopped (media task stopped) */
- if (!btif_a2dp_source_is_streaming()) {
- osi_free(p_buf);
- return false;
- }
-
- /* Check if the transmission queue has been flushed */
+ // Check if the transmission queue has been flushed.
if (btif_a2dp_source_cb.tx_flush) {
log::verbose("tx suspended, discarded frame");
@@ -1011,12 +1017,10 @@ static bool btif_a2dp_source_enqueue_callback(BT_HDR* p_buf, size_t frames_n,
}
}
- /* Update the statistics */
+ // Update the statistics.
btif_a2dp_source_cb.stats.tx_queue_total_frames += frames_n;
btif_a2dp_source_cb.stats.tx_queue_max_frames_per_packet =
std::max(frames_n, btif_a2dp_source_cb.stats.tx_queue_max_frames_per_packet);
- log::assert_that(btif_a2dp_source_cb.encoder_interface != nullptr,
- "assert failed: btif_a2dp_source_cb.encoder_interface != nullptr");
fixed_queue_enqueue(btif_a2dp_source_cb.tx_audio_queue, p_buf);
@@ -1043,8 +1047,7 @@ static void btif_a2dp_source_audio_tx_flush_event(void) {
static bool btif_a2dp_source_audio_tx_flush_req(void) {
log::info("state={}", btif_a2dp_source_cb.StateStr());
- btif_a2dp_source_thread.DoInThread(FROM_HERE,
- base::BindOnce(&btif_a2dp_source_audio_tx_flush_event));
+ local_thread()->DoInThread(FROM_HERE, base::BindOnce(&btif_a2dp_source_audio_tx_flush_event));
return true;
}
@@ -1254,15 +1257,11 @@ static void btif_a2dp_source_update_metrics(void) {
A2dpSessionMetrics metrics;
metrics.codec_index = stats.codec_index;
metrics.is_a2dp_offload = btif_av_is_a2dp_offload_running();
+
// session_start_us is 0 when btif_a2dp_source_start_audio_req() is not called
// mark the metric duration as invalid (-1) in this case
if (stats.session_start_us != 0) {
- int64_t session_end_us = stats.session_end_us == 0
- ? bluetooth::common::time_get_os_boottime_us()
- : stats.session_end_us;
- if (static_cast<uint64_t>(session_end_us) > stats.session_start_us) {
- metrics.audio_duration_ms = (session_end_us - stats.session_start_us) / 1000;
- }
+ metrics.audio_duration_ms = (stats.session_end_us - stats.session_start_us) / 1000;
}
if (enqueue_stats.total_updates > 1) {
diff --git a/system/btif/src/btif_av.cc b/system/btif/src/btif_av.cc
index c62d54c281..2132172e48 100644
--- a/system/btif/src/btif_av.cc
+++ b/system/btif/src/btif_av.cc
@@ -52,6 +52,7 @@
#include "device/include/device_iot_config.h"
#include "hardware/bt_av.h"
#include "include/hardware/bt_rc.h"
+#include "os/logging/log_adapter.h"
#include "osi/include/alarm.h"
#include "osi/include/allocator.h"
#include "osi/include/properties.h"
diff --git a/system/btif/src/btif_hh.cc b/system/btif/src/btif_hh.cc
index 2de9feb1ed..e01e2d8d75 100644
--- a/system/btif/src/btif_hh.cc
+++ b/system/btif/src/btif_hh.cc
@@ -1283,6 +1283,9 @@ static void btif_hh_upstreams_evt(uint16_t event, char* p_param) {
case BTA_HH_API_ERR_EVT:
log::error("BTA_HH API_ERR");
break;
+ case BTA_HH_DATA_EVT:
+ // data output is sent - do nothing.
+ break;
default:
log::warn("Unhandled event: {}", event);
break;
diff --git a/system/btif/src/btif_profile_queue.cc b/system/btif/src/btif_profile_queue.cc
index b640c70d02..15237abe75 100644
--- a/system/btif/src/btif_profile_queue.cc
+++ b/system/btif/src/btif_profile_queue.cc
@@ -30,7 +30,6 @@
#include <base/functional/bind.h>
#include <base/functional/callback.h>
-#include <base/strings/stringprintf.h>
#include <bluetooth/log.h>
#include <string.h>
@@ -53,8 +52,7 @@ public:
: address_(address), uuid_(uuid), busy_(false), connect_cb_(connect_cb) {}
std::string ToString() const {
- return base::StringPrintf("address=%s UUID=%04X busy=%s", ADDRESS_TO_LOGGABLE_CSTR(address_),
- uuid_, (busy_) ? "true" : "false");
+ return fmt::format("address={} UUID={:04X} busy={}", address_, uuid_, busy_);
}
const RawAddress& address() const { return address_; }
diff --git a/system/btif/src/btif_rc.cc b/system/btif/src/btif_rc.cc
index a059d5a05f..cf244403b1 100644
--- a/system/btif/src/btif_rc.cc
+++ b/system/btif/src/btif_rc.cc
@@ -44,6 +44,7 @@
#include "btif_common.h"
#include "btif_util.h"
#include "device/include/interop.h"
+#include "os/logging/log_adapter.h"
#include "osi/include/alarm.h"
#include "osi/include/allocator.h"
#include "osi/include/list.h"
diff --git a/system/build/Android.bp b/system/build/Android.bp
index fd6636b0c5..13f1ccccf5 100644
--- a/system/build/Android.bp
+++ b/system/build/Android.bp
@@ -11,6 +11,7 @@ cc_defaults {
name: "fluoride_defaults",
defaults: [
"bluetooth_cflags",
+ "bluetooth_tidy",
],
cflags: [
"-DEXPORT_SYMBOL=__attribute__((visibility(\"default\")))",
diff --git a/system/common/base_bind_unittest.cc b/system/common/base_bind_unittest.cc
index d31ea01642..b4f35f53e4 100644
--- a/system/common/base_bind_unittest.cc
+++ b/system/common/base_bind_unittest.cc
@@ -24,8 +24,6 @@
#include <memory>
#include <mutex>
-#include "os/log.h"
-
class BaseBindThreadTest : public ::testing::Test {
public:
protected:
diff --git a/system/device/src/device_iot_config.cc b/system/device/src/device_iot_config.cc
index 0918a54f7b..2da612ac47 100644
--- a/system/device/src/device_iot_config.cc
+++ b/system/device/src/device_iot_config.cc
@@ -32,7 +32,6 @@
#include "device_iot_config_int.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/alarm.h"
#include "osi/include/allocator.h"
#include "osi/include/compat.h"
diff --git a/system/device/src/device_iot_config_int.cc b/system/device/src/device_iot_config_int.cc
index 60f2d884bd..33b5f8106d 100644
--- a/system/device/src/device_iot_config_int.cc
+++ b/system/device/src/device_iot_config_int.cc
@@ -32,7 +32,6 @@
#include "btcore/include/module.h"
#include "btif/include/btif_common.h"
#include "device/include/device_iot_config.h"
-#include "os/log.h"
#include "osi/include/alarm.h"
#include "osi/include/config.h"
#include "osi/include/future.h"
diff --git a/system/device/src/interop.cc b/system/device/src/interop.cc
index 78b1b70b34..c45031a7b0 100644
--- a/system/device/src/interop.cc
+++ b/system/device/src/interop.cc
@@ -40,7 +40,6 @@
#include "btif/include/btif_storage.h"
#include "device/include/interop_config.h"
#include "device/include/interop_database.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/compat.h"
#include "osi/include/config.h"
diff --git a/system/gd/Android.bp b/system/gd/Android.bp
index 5f67289b2f..579aae7d44 100644
--- a/system/gd/Android.bp
+++ b/system/gd/Android.bp
@@ -12,9 +12,7 @@ cc_defaults {
name: "gd_defaults",
defaults: [
"bluetooth_cflags",
- ],
- tidy_checks: [
- "-performance-unnecessary-value-param",
+ "bluetooth_tidy",
],
target: {
android: {
@@ -39,56 +37,6 @@ cc_defaults {
header_libs: ["jni_headers"],
}
-cc_defaults {
- name: "gd_clang_tidy",
- tidy: true,
- tidy_checks: [
- "-bugprone*",
- "-cert-dcl21-cpp", // warning: overloaded returns a non-constant object instead of a constant object type
- "-cert-dcl59-cpp", // warning: do not use unnamed namespaces in header files
- "-cert-msc30-c", // warning: rand() has limited randomness; use C++11 random library instead
- "-cert-msc50-cpp", // warning: rand() has limited randomness; use C++11 random library instead
- "-cert-oop54-cpp", // warning: operator=() does not handle self-assignment properly
- "-google*",
- "-performance*",
- "clang-analyzer-core.CallAndMessage",
- "clang-analyzer-optin.cplusplus.UninitializedObject",
- ],
- tidy_checks_as_errors: [
- "clang-analyzer-core.CallAndMessage",
- "clang-analyzer-optin.cplusplus.UninitializedObject",
- "cppcoreguidelines-pro-type-member-init",
- ],
- tidy_flags: [
- "--header-filter=^.*packages/modules/Bluetooth/system/.*.h$",
-
- "--extra-arg-before=-Xclang",
- "--extra-arg-before=-analyzer-config",
-
- "--extra-arg-before=-Xclang",
- "--extra-arg-before=optin.cplusplus.UninitializedObject:Pedantic=true",
-
- "--extra-arg-before=-Xclang",
- "--extra-arg-before=-analyzer-config",
-
- "--extra-arg-before=-Xclang",
- "--extra-arg-before=optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true",
-
- ],
-}
-
-// Clang is targeted for android core libraries but other base libraries
-// may not support clang tidy recommendations (e.g. MacOS)
-cc_defaults {
- name: "gd_clang_tidy_ignore_android",
- tidy: true,
- tidy_checks: [
- "-android-cloexec-accept", // warning: prefer accept4() to accept() because accept4() allows SOCK_CLOEXEC
- "-android-cloexec-pipe2", // warning: 'pipe2' should use O_CLOEXEC where possible
- "-android-cloexec-socket", // warning: 'pipe2' should use O_CLOEXEC where possible
- ],
-}
-
soong_config_module_type {
name: "mgmt_cc_defaults",
module_type: "cc_defaults",
diff --git a/system/gd/README.md b/system/gd/README.md
index 18a021132c..862bb3897c 100644
--- a/system/gd/README.md
+++ b/system/gd/README.md
@@ -7,7 +7,6 @@ Please see this [informative video we've prepared](https://www.youtube.com/watch
Guidelines for developing the Gabeldorsche (GD) stack
* [Architecture](./docs/architecture/architecture.md)
-* [Style Guide](./docs/architecture/style_guide.md)
### Testing
diff --git a/system/gd/common/audit_log.cc b/system/gd/common/audit_log.cc
index 74be6f25c9..5897c70aac 100644
--- a/system/gd/common/audit_log.cc
+++ b/system/gd/common/audit_log.cc
@@ -16,9 +16,12 @@
#include "common/audit_log.h"
+#ifdef __ANDROID__
+#include <log/log_event_list.h>
+#endif // __ANDROID__
+
#include "common/strings.h"
#include "hci/hci_packets.h"
-#include "os/log.h"
namespace {
#if defined(__ANDROID__) && !defined(FUZZ_TARGET)
diff --git a/system/gd/common/byte_array_test.cc b/system/gd/common/byte_array_test.cc
index 4798faccf0..b9a64b3882 100644
--- a/system/gd/common/byte_array_test.cc
+++ b/system/gd/common/byte_array_test.cc
@@ -18,8 +18,6 @@
#include <gtest/gtest.h>
-#include "os/log.h"
-
using bluetooth::common::ByteArray;
namespace {
diff --git a/system/gd/common/circular_buffer_test.cc b/system/gd/common/circular_buffer_test.cc
index 577bb6681b..e35a60c98e 100644
--- a/system/gd/common/circular_buffer_test.cc
+++ b/system/gd/common/circular_buffer_test.cc
@@ -22,8 +22,6 @@
#include <limits>
#include <string>
-#include "os/log.h"
-
namespace testing {
long long timestamp_{0};
diff --git a/system/gd/common/lru_cache.h b/system/gd/common/lru_cache.h
index 75b104f268..303688d55f 100644
--- a/system/gd/common/lru_cache.h
+++ b/system/gd/common/lru_cache.h
@@ -27,7 +27,6 @@
#include <unordered_map>
#include "common/list_map.h"
-#include "os/log.h"
namespace bluetooth {
namespace common {
diff --git a/system/gd/common/metric_id_manager.cc b/system/gd/common/metric_id_manager.cc
index 84268dba1d..131b09402c 100644
--- a/system/gd/common/metric_id_manager.cc
+++ b/system/gd/common/metric_id_manager.cc
@@ -27,8 +27,6 @@
#include <optional>
#include <thread>
-#include "os/log.h"
-
namespace bluetooth {
namespace common {
diff --git a/system/gd/common/strings.h b/system/gd/common/strings.h
index ed5af390aa..5593715eb2 100644
--- a/system/gd/common/strings.h
+++ b/system/gd/common/strings.h
@@ -32,7 +32,6 @@
#include <vector>
#include "common/type_helper.h"
-#include "os/log.h"
namespace bluetooth {
namespace common {
diff --git a/system/gd/common/sync_map_count_test.cc b/system/gd/common/sync_map_count_test.cc
index 189e6f47c6..0e29c32467 100644
--- a/system/gd/common/sync_map_count_test.cc
+++ b/system/gd/common/sync_map_count_test.cc
@@ -23,8 +23,6 @@
#include <cstring>
#include <vector>
-#include "os/log.h"
-
namespace testing {
const char* data[] = {
diff --git a/system/gd/docs/architecture/style_guide.md b/system/gd/docs/architecture/style_guide.md
deleted file mode 100644
index bdc5657f9a..0000000000
--- a/system/gd/docs/architecture/style_guide.md
+++ /dev/null
@@ -1,209 +0,0 @@
-# Gabeldorsche Style Guide
-
-[TOC]
-
-## Base
-
-In general, when not mentioned in this document, developers should follow the
-Google C++ and Google Java style guide as much as possible.
-
-### Google C++ Style Guide
-
-C++ Style Guide: https://google.github.io/styleguide/cppguide.html
-
-### Android and Google Java Style Guide
-
-1. Android Java Style Guide:
- https://source.android.com/setup/contribute/code-style
-
-2. when not covered by (1), see External Java Style Guide:
- https://google.github.io/styleguide/javaguide.html
-
-line length limit is 120 characters for C++ and Java
-
-### Python Style Guide
-
-The GD stack uses the Google Python Style Guide:
-
-* http://google.github.io/styleguide/pyguide.html
-
-with the following modifications as shown in the
-[.style.yapf](https://android.googlesource.com/platform/packages/modules/Bluetooth/system/+/refs/heads/master/.style.yapf) definition:
-
-```yapf
-based_on_style: google
-indent_width: 4
-column_limit: 120
-```
-
-## Build files
-
-* One build target for the entire stack in packages/modules/Bluetooth/system (i.e. one cc_library())
- * If only part of the stack needs to be compiled, configure it using the
- “target” configuration in Android.bp
-* One build target for all unit tests (i.e. one cc_test)
-* When needed, filgroup() can be created in Android.bp in sub-directories. The
- main build target should use these filegroups() to build the main output
- library.
-* All targets must have host_supported == true unless it is dependent on the
- OS
-* If the stack needs to be compiled using other build system, then the build
- files should also live in packages/modules/Bluetooth/system
-
-## Namespace and include
-
-* Namespace must follow directory names
-* Top level namespace for internal code is “bluetooth”
-* Top level namespace for externally visible code is “android::bluetooth”
-* Include path must be relative to the root directory of the stack. Normally
- it is packages/modules/Bluetooth/system, for GD refactor code, it is packages/modules/Bluetooth/system/gd
-
-## Multiple implementations of the same header
-
-Since GD interact with many lower level components that are platform dependent,
-frequently there is need to implement the same header multiple times for
-different platform or hardware. When doing this:
-
-* Avoid #define macros as much as possible. Instead put code into different
- source files and selectively compile them for different targets.
-* Convention of operating system used:
- * android/
- * All Android devices that use HIDL
- * linux/
- * All non-Android linux devices
- * linux_generic/
- * Android and non-Android linux devices
-
-## Directory structure
-
-Root directory under Android tree:
-[**packages/modules/Bluetooth/system/gd/**](https://android.googlesource.com/platform/packages/modules/Bluetooth/system/+/refs/heads/master/gd/)
-
-* Directory structure should be as flat as possible
-* Each file should contain at most one class
-* Header, source code, and unit test should live in the same directory with
- the following naming guideline:
- * Source: bb.cc
- * Header: bb.h
- * Test: bb_test.cc
-* Each profile should have its own directory and module
-* Source and sink, server and client profiles should live in two sub folders
- of the same common directory where common code can be stored. However,
- source and sink must have separate modules
-* Module file is also the external API header
-* Prefer underscore over dashes
-
-### Example: utility library with OS dependent implementation
-
-* os/: OS dependent classes such as Alarm, Thread, Handler
- * Android.bp: Build file that defines file groups that would include
- different source files based on compile time target
- * alarm.h: common header for alarm
- * linux_generic/: Implementations for generic Linux OS
- * alarm.cc: Linux generic implementation of alarm.h using timer_fd
- * alarm_test.cc: unit test for alarm.h
- * fuzz/: library needed for fuzz tests in the os/ library
-
-### Example: module with hardware dependent implementation
-
-* hal/: Hardware abstraction layer such as HCI interfaces, Audio interfaces
- * Android.bp: Build file that defines file groups that would include
- different source files based on compile time target
- * hci_hal.h: common library header
- * hci_hal_android_hidl.cc: implementation of hci_hal.h using Android HIDL
- * hci_hal_android_hidl_test.cc: unit tests for the Android HIDL
- implementation
- * hci_hal_host.cc: implementation of hci_hal.h using linux Bluetooth HCI
- socket
- * hci_hal_host_rootcanal.cc: implementation of hci_hal.h using root-canal
- emulator
- * hci_hal_host_test.cc: unit tests for the socket based HAL (root-canal)
- emulator implementation
- * facade.proto: gRPC automation interface definition for this layer
- * facade.h/cc: an implementation of the above gRPC interface for the GD
- stack
- * cert/: certification tests for this module
- * fuzz/: library needed for fuzz tests in the hal/ module
-
-### Example: similar protocol with the same base
-
-* l2cap/: L2CAP layer, splitted among classic and LE
- * classic/: Classic L2CAP module
- * cert/: certification tests for this module
- * internal/: internal code to be used only in classic
- * Source code and headers being exported to other modules
- * le/: LE L2CAP module
- * cert/: certification tests for this module
- * internal/: internal code to be used only in classic
- * Source code and headers being exported to other modules
- * internal/: L2CAP internal code that should not be used by sources
- outside L2CAP
- * data_pipeline_manager.h
- * data_pipeline_manager.cc
- * data_pipeline_manager_mock.h: Mock of this class, used in unit tests
- * dynamic_channel_allocator.h
- * dynamic_channel_allocator.cc
- * dynamic_channel_allocator_test.cc: GTest unit test of this class
- * dynamic_channel_allocator_fuzz_test.cc: Fuzz test of this class
- * *.h/.cc: Common headers and sources that is exposed to other modules
-
-### Example: protocol or profiles with client and server side implementations
-
-* a2dp/: A2DP profile
- * sink/: A2DP sink module (e.g. headset)
- * source/: A2DP source module (e.g. phone)
-* avrcp/
- * controller/: AVRCP peripheral module (e.g. carkit)
- * target/: AVRCP target module (e.g. Phone)
-* hfp/
- * hf/: Handsfree device (e.g. headset)
- * ag/: Audio gateway (e.g. phone)
-
-## External libraries
-
-To maintain high portability, we are trying to stick with C++ STL as much as
-possible. Hence, before including an external library, please ask the team for
-review.
-
-Examples of currently used libraries:
-
-* boringssl: Google's openssl implementation
-* small parts of libchrome, to be removed or replaced eventually
- * base::OnceCallback
- * base::Callback
- * base::BindOnce
- * base::Bind
-* google-breakpad: host binary crash handler
-* libunwindstack: print stacktrace on crash on host
-
-## Exposed symbols
-
-Given that entire Fluoride library is held in libbluetooth.so dynamic library
-file, we need a way to load this library and extract entry points to it. The
-only symbols that should be exposed are:
-
-* An entry point to a normal running adapter module libbluetooth.so
-* A header library to all exposed API service to profiles and layers
-* An entry point to a certification interface, libbluetooth\_certification.so
-* A header library to this certification stack
-
-## Logging
-
-Gabeldorsche uses `printf` style logging with macros defined in `os/log.h`. Five
-log levels are available.
-
-* LOG_VERBOSE(fmt, args...): Will be disabled by default
-* LOG_INFO(fmt, args...): Will be disabled by default
-* LOG_INFO(fmt, args...): Enabled
-* LOG_WARN(fmt, args...): Enabled
-* LOG_ERROR(fmt, args...): Enabled
-* LOG_ALWAYS_FATAL(fmt, args...): Enabled, will always crash
-* ASSERT(condition): Enabled, will crash when condition is false
-* ASSERT_LOG(conditon, fmt, args...): Enabled, will crash and print log when
- condition is false
-
-In general, errors that are caused by remote device should never crash our stack
-and should be logged using LOG_WARN() only. Recoverable errors due to our stack
-or badly behaved bluetooth controller firmware should be logged using
-LOG_ERROR() before recovery. Non-recoverable errors should be logged as
-LOG_ALWAYS_FATAL() to crash the stack and restart.
diff --git a/system/gd/docs/testing/gtest.md b/system/gd/docs/testing/gtest.md
index 5120250a22..9ec38f8215 100644
--- a/system/gd/docs/testing/gtest.md
+++ b/system/gd/docs/testing/gtest.md
@@ -134,7 +134,6 @@ Note: All paths are relative to
#include "l2cap/internal/channel_impl.h"
#include "l2cap/l2cap_packets.h"
#include "os/handler.h"
-#include "os/log.h"
namespace bluetooth {
namespace l2cap {
diff --git a/system/gd/dumpsys/Android.bp b/system/gd/dumpsys/Android.bp
index 085c44b7f9..84074824ac 100644
--- a/system/gd/dumpsys/Android.bp
+++ b/system/gd/dumpsys/Android.bp
@@ -27,7 +27,6 @@ filegroup {
genrule {
name: "BluetoothGeneratedDumpsysTestData_h",
- visibility: ["//visibility:public"],
tools: [
"flatc",
],
@@ -155,7 +154,6 @@ cc_library {
name: "libbluetooth-dumpsys",
host_supported: true,
defaults: [
- "gd_clang_tidy",
"gd_defaults",
],
generated_sources: [
@@ -171,7 +169,6 @@ cc_library {
name: "libbluetooth-dumpsys-test",
host_supported: true,
defaults: [
- "gd_clang_tidy",
"gd_defaults",
],
generated_sources: [
@@ -183,7 +180,6 @@ cc_library {
name: "libbluetooth-dumpsys-unittest",
host_supported: true,
defaults: [
- "gd_clang_tidy",
"gd_defaults",
],
generated_headers: [
diff --git a/system/gd/dumpsys/internal/filter_internal.cc b/system/gd/dumpsys/internal/filter_internal.cc
index a26c56383f..2db2878f95 100644
--- a/system/gd/dumpsys/internal/filter_internal.cc
+++ b/system/gd/dumpsys/internal/filter_internal.cc
@@ -23,7 +23,6 @@
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
-#include "os/log.h"
#define DBG 0
diff --git a/system/gd/dumpsys/internal/filter_internal_test.cc b/system/gd/dumpsys/internal/filter_internal_test.cc
index 2db4b2d007..38f3481f0c 100644
--- a/system/gd/dumpsys/internal/filter_internal_test.cc
+++ b/system/gd/dumpsys/internal/filter_internal_test.cc
@@ -27,7 +27,6 @@
#include "dumpsys/internal/test_data/string_generated.h"
#include "dumpsys/internal/test_data/struct_bfbs.h"
#include "dumpsys/internal/test_data/struct_generated.h"
-#include "os/log.h"
namespace testing {
diff --git a/system/gd/dumpsys/reflection_schema.cc b/system/gd/dumpsys/reflection_schema.cc
index 3ab9fc2803..b2d79313eb 100644
--- a/system/gd/dumpsys/reflection_schema.cc
+++ b/system/gd/dumpsys/reflection_schema.cc
@@ -23,7 +23,6 @@
#include "bundler_schema_generated.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
-#include "os/log.h"
using namespace bluetooth;
diff --git a/system/gd/facade/grpc_root_server.cc b/system/gd/facade/grpc_root_server.cc
index 886e6d9b30..8e3bfb3f3f 100644
--- a/system/gd/facade/grpc_root_server.cc
+++ b/system/gd/facade/grpc_root_server.cc
@@ -30,7 +30,6 @@
#include "hci/facade/le_initiator_address_facade.h"
#include "hci/facade/le_scanning_manager_facade.h"
#include "neighbor/facade/facade.h"
-#include "os/log.h"
#include "os/thread.h"
#include "stack_manager.h"
diff --git a/system/gd/grpc/grpc_event_queue.h b/system/gd/grpc/grpc_event_queue.h
index c181573ab1..c7f8c87314 100644
--- a/system/gd/grpc/grpc_event_queue.h
+++ b/system/gd/grpc/grpc_event_queue.h
@@ -25,7 +25,6 @@
#include "blueberry/facade/common.pb.h"
#include "common/blocking_queue.h"
-#include "os/log.h"
namespace bluetooth {
namespace grpc {
diff --git a/system/gd/grpc/grpc_module.cc b/system/gd/grpc/grpc_module.cc
index 93979f533e..53b40f8035 100644
--- a/system/gd/grpc/grpc_module.cc
+++ b/system/gd/grpc/grpc_module.cc
@@ -18,8 +18,6 @@
#include <bluetooth/log.h>
-#include "os/log.h"
-
using ::grpc::Server;
using ::grpc::ServerBuilder;
diff --git a/system/gd/hal/hci_hal_host.cc b/system/gd/hal/hci_hal_host.cc
index c6bba6968a..79e1cabd85 100644
--- a/system/gd/hal/hci_hal_host.cc
+++ b/system/gd/hal/hci_hal_host.cc
@@ -37,7 +37,6 @@
#include "hal/mgmt.h"
#include "hal/snoop_logger.h"
#include "metrics/counter_metrics.h"
-#include "os/log.h"
#include "os/reactor.h"
#include "os/thread.h"
diff --git a/system/gd/hal/hci_hal_host_rootcanal.cc b/system/gd/hal/hci_hal_host_rootcanal.cc
index 26ffa84894..05d898228d 100644
--- a/system/gd/hal/hci_hal_host_rootcanal.cc
+++ b/system/gd/hal/hci_hal_host_rootcanal.cc
@@ -31,7 +31,6 @@
#include "hal/hci_hal_host.h"
#include "hal/snoop_logger.h"
#include "metrics/counter_metrics.h"
-#include "os/log.h"
#include "os/reactor.h"
#include "os/thread.h"
diff --git a/system/gd/hal/hci_hal_host_test.cc b/system/gd/hal/hci_hal_host_test.cc
index 14c689738e..ab0ccef8f6 100644
--- a/system/gd/hal/hci_hal_host_test.cc
+++ b/system/gd/hal/hci_hal_host_test.cc
@@ -34,7 +34,6 @@
#include "hal/hci_hal.h"
#include "hal/serialize_packet.h"
-#include "os/log.h"
#include "os/thread.h"
#include "os/utils.h"
#include "packet/raw_builder.h"
diff --git a/system/gd/hal/mgmt.cc b/system/gd/hal/mgmt.cc
index dd2e0bca6e..c5de32c3f7 100644
--- a/system/gd/hal/mgmt.cc
+++ b/system/gd/hal/mgmt.cc
@@ -30,8 +30,6 @@
#include <cerrno>
-#include "os/log.h"
-
extern int GetAdapterIndex();
namespace bluetooth {
diff --git a/system/gd/hal/ranging_hal_android.cc b/system/gd/hal/ranging_hal_android.cc
index 658b7d777b..893a25fd10 100644
--- a/system/gd/hal/ranging_hal_android.cc
+++ b/system/gd/hal/ranging_hal_android.cc
@@ -23,7 +23,7 @@
#include <unordered_map>
-// AIDL uses syslog.h, so these defines conflict with os/log.h
+// AIDL uses syslog.h, so these defines conflict with log/log.h
#undef LOG_DEBUG
#undef LOG_INFO
#undef LOG_WARNING
diff --git a/system/gd/hal/ranging_hal_host.cc b/system/gd/hal/ranging_hal_host.cc
index 16e44995b6..36c821f419 100644
--- a/system/gd/hal/ranging_hal_host.cc
+++ b/system/gd/hal/ranging_hal_host.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-// AIDL uses syslog.h, so these defines conflict with os/log.h
+// AIDL uses syslog.h, so these defines conflict with log/log.h
#undef LOG_DEBUG
#undef LOG_INFO
#undef LOG_WARNING
diff --git a/system/gd/hci/acl_manager/assembler.h b/system/gd/hci/acl_manager/assembler.h
index 147cc7a99e..d126a980a2 100644
--- a/system/gd/hci/acl_manager/assembler.h
+++ b/system/gd/hci/acl_manager/assembler.h
@@ -26,7 +26,6 @@
#include "hci/acl_manager/acl_connection.h"
#include "hci/address_with_type.h"
#include "os/handler.h"
-#include "os/log.h"
#include "packet/packet_view.h"
namespace bluetooth {
diff --git a/system/gd/hci/acl_manager/classic_acl_connection_test.cc b/system/gd/hci/acl_manager/classic_acl_connection_test.cc
index 8cc66ab807..97ee9fc4af 100644
--- a/system/gd/hci/acl_manager/classic_acl_connection_test.cc
+++ b/system/gd/hci/acl_manager/classic_acl_connection_test.cc
@@ -33,7 +33,6 @@
#include "hci/address.h"
#include "hci/hci_packets.h"
#include "os/handler.h"
-#include "os/log.h"
#include "os/thread.h"
using namespace bluetooth;
diff --git a/system/gd/hci/acl_manager/round_robin_scheduler_test.cc b/system/gd/hci/acl_manager/round_robin_scheduler_test.cc
index 210cc71125..f019bf8fe1 100644
--- a/system/gd/hci/acl_manager/round_robin_scheduler_test.cc
+++ b/system/gd/hci/acl_manager/round_robin_scheduler_test.cc
@@ -23,7 +23,6 @@
#include "hci/controller.h"
#include "hci/hci_packets.h"
#include "os/handler.h"
-#include "os/log.h"
#include "packet/raw_builder.h"
using ::bluetooth::common::BidiQueue;
diff --git a/system/gd/hci/distance_measurement_manager.cc b/system/gd/hci/distance_measurement_manager.cc
index d448de6264..b5d84af804 100644
--- a/system/gd/hci/distance_measurement_manager.cc
+++ b/system/gd/hci/distance_measurement_manager.cc
@@ -32,7 +32,6 @@
#include "hci/hci_layer.h"
#include "module.h"
#include "os/handler.h"
-#include "os/log.h"
#include "os/repeating_alarm.h"
#include "packet/packet_view.h"
#include "ras/ras_packets.h"
@@ -63,14 +62,13 @@ static constexpr uint16_t kMaxProcedureInterval = 0xFF;
static constexpr uint16_t kMaxProcedureCount = 0x01;
static constexpr uint32_t kMinSubeventLen = 0x0004E2; // 1250us
static constexpr uint32_t kMaxSubeventLen = 0x3d0900; // 4s
-static constexpr uint8_t kToneAntennaConfigSelection = 0x00; // 1x1
static constexpr uint8_t kTxPwrDelta = 0x00;
static constexpr uint8_t kProcedureDataBufferSize = 0x10; // Buffer size of Procedure data
static constexpr uint16_t kMtuForRasData = 507; // 512 - 5
static constexpr uint16_t kRangingCounterMask = 0x0FFF;
static constexpr uint8_t kInvalidConfigId = 0xFF;
static constexpr uint16_t kDefaultIntervalMs = 1000; // 1s
-static constexpr uint8_t kPreferredPeerAntennaValue = 0x01; // Use first ordered antenna element
+static constexpr uint8_t kMaxRetryCounterForCreateConfig = 0x03;
struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
struct CsProcedureData {
@@ -143,21 +141,37 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
std::unique_ptr<os::RepeatingAlarm> repeating_alarm;
};
+ // TODO: use state machine to manage the tracker.
+ enum class CsTrackerState : uint8_t {
+ UNSPECIFIED = 0x00,
+ STOPPED = 1 << 0,
+ INIT = 1 << 1,
+ RAS_CONNECTED = 1 << 2,
+ WAIT_FOR_CONFIG_COMPLETE = 1 << 3,
+ WAIT_FOR_SECURITY_ENABLED = 1 << 4,
+ WAIT_FOR_PROCEDURE_ENABLED = 1 << 5,
+ STARTED = 1 << 6,
+ };
+
struct CsTracker {
+ CsTrackerState state = CsTrackerState::STOPPED;
Address address;
hci::Role local_hci_role = hci::Role::CENTRAL;
uint16_t procedure_counter = 0;
CsRole role = CsRole::INITIATOR;
bool local_start = false; // If the CS was started by the local device.
+ // TODO: clean up, replace the measurement_ongoing with STOPPED
bool measurement_ongoing = false;
bool ras_connected = false;
bool setup_complete = false;
bool config_set = false;
+ uint8_t retry_counter_for_create_config = 0;
uint16_t n_procedure_count = 0;
CsMainModeType main_mode_type = CsMainModeType::MODE_2;
CsSubModeType sub_mode_type = CsSubModeType::UNUSED;
CsRttType rtt_type = CsRttType::RTT_AA_ONLY;
bool remote_support_phase_based_ranging = false;
+ uint8_t remote_num_antennas_supported_ = 0x01;
uint8_t config_id = kInvalidConfigId;
uint8_t selected_tx_power = 0;
std::vector<CsProcedureData> procedure_data_list = {};
@@ -316,6 +330,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
if (it->second.repeating_alarm == nullptr) {
it->second.repeating_alarm = std::make_unique<os::RepeatingAlarm>(handler_);
}
+ it->second.state = CsTrackerState::INIT;
it->second.interval_ms = interval;
it->second.local_start = true;
it->second.measurement_ongoing = true;
@@ -383,8 +398,9 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
log::warn("Can't find CS tracker for {}", address);
} else if (it->second.measurement_ongoing) {
it->second.repeating_alarm->Cancel();
- reset_tracker_on_stopped(it->second);
send_le_cs_procedure_enable(connection_handle, Enable::DISABLED);
+ // does not depend on the 'disable' command result.
+ reset_tracker_on_stopped(it->second);
}
} break;
}
@@ -408,6 +424,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
return;
}
it->second.ras_connected = true;
+ it->second.state = CsTrackerState::RAS_CONNECTED;
if (ranging_hal_->IsBound()) {
ranging_hal_->OpenSession(connection_handle, att_handle, vendor_specific_data);
@@ -466,6 +483,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
cs_responder_trackers_[connection_handle] = CsTracker();
it = cs_responder_trackers_.find(connection_handle);
}
+ it->second.state = CsTrackerState::RAS_CONNECTED;
it->second.address = identity_address;
it->second.local_start = false;
it->second.local_hci_role = local_hci_role;
@@ -568,6 +586,10 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
}
void send_le_cs_security_enable(uint16_t connection_handle) {
+ if (cs_requester_trackers_.find(connection_handle) == cs_requester_trackers_.end()) {
+ log::warn("no cs tracker found for {}", connection_handle);
+ }
+ cs_requester_trackers_[connection_handle].state = CsTrackerState::WAIT_FOR_SECURITY_ENABLED;
hci_layer_->EnqueueCommand(
LeCsSecurityEnableBuilder::Create(connection_handle),
handler_->BindOnceOn(this, &impl::on_cs_setup_command_status_cb, connection_handle));
@@ -582,6 +604,10 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
}
void send_le_cs_create_config(uint16_t connection_handle, uint8_t config_id) {
+ if (cs_requester_trackers_.find(connection_handle) == cs_requester_trackers_.end()) {
+ log::warn("no cs tracker found for {}", connection_handle);
+ }
+ cs_requester_trackers_[connection_handle].state = CsTrackerState::WAIT_FOR_CONFIG_COMPLETE;
auto channel_vector = common::FromHexString("1FFFFFFFFFFFFC7FFFFC"); // use all 72 Channel
std::array<uint8_t, 10> channel_map;
std::copy(channel_vector->begin(), channel_vector->end(), channel_map.begin());
@@ -591,32 +617,44 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
connection_handle, config_id, CsCreateContext::BOTH_LOCAL_AND_REMOTE_CONTROLLER,
CsMainModeType::MODE_2, CsSubModeType::UNUSED, kMinMainModeSteps,
kMaxMainModeSteps, kMainModeRepetition, kMode0Steps, CsRole::INITIATOR,
- CsConfigRttType::RTT_AA_ONLY, CsSyncPhy::LE_1M_PHY, channel_map,
+ CsConfigRttType::RTT_AA_COARSE, CsSyncPhy::LE_1M_PHY, channel_map,
kChannelMapRepetition, CsChannelSelectionType::TYPE_3B, CsCh3cShape::HAT_SHAPE,
kCh3cJump),
handler_->BindOnceOn(this, &impl::on_cs_setup_command_status_cb, connection_handle));
}
- void send_le_cs_set_procedure_parameters(uint16_t connection_handle, uint8_t config_id) {
+ void send_le_cs_set_procedure_parameters(uint16_t connection_handle, uint8_t config_id,
+ uint8_t remote_num_antennas_supported) {
+ uint8_t tone_antenna_config_selection =
+ cs_tone_antenna_config_mapping_table_[num_antennas_supported_ - 1]
+ [remote_num_antennas_supported - 1];
+ uint8_t preferred_peer_antenna_value =
+ cs_preferred_peer_antenna_mapping_table_[tone_antenna_config_selection];
+ log::info(
+ "num_antennas_supported:{}, remote_num_antennas_supported:{}, "
+ "tone_antenna_config_selection:{}, preferred_peer_antenna:{}",
+ num_antennas_supported_, remote_num_antennas_supported, tone_antenna_config_selection,
+ preferred_peer_antenna_value);
CsPreferredPeerAntenna preferred_peer_antenna;
- preferred_peer_antenna.use_first_ordered_antenna_element_ = kPreferredPeerAntennaValue & 0x01;
+ preferred_peer_antenna.use_first_ordered_antenna_element_ = preferred_peer_antenna_value & 0x01;
preferred_peer_antenna.use_second_ordered_antenna_element_ =
- (kPreferredPeerAntennaValue >> 1) & 0x01;
+ (preferred_peer_antenna_value >> 1) & 0x01;
preferred_peer_antenna.use_third_ordered_antenna_element_ =
- (kPreferredPeerAntennaValue >> 2) & 0x01;
+ (preferred_peer_antenna_value >> 2) & 0x01;
preferred_peer_antenna.use_fourth_ordered_antenna_element_ =
- (kPreferredPeerAntennaValue >> 3) & 0x01;
+ (preferred_peer_antenna_value >> 3) & 0x01;
hci_layer_->EnqueueCommand(
LeCsSetProcedureParametersBuilder::Create(
connection_handle, config_id, kMaxProcedureLen, kMinProcedureInterval,
kMaxProcedureInterval, kMaxProcedureCount, kMinSubeventLen, kMaxSubeventLen,
- kToneAntennaConfigSelection, CsPhy::LE_1M_PHY, kTxPwrDelta,
+ tone_antenna_config_selection, CsPhy::LE_1M_PHY, kTxPwrDelta,
preferred_peer_antenna, CsSnrControl::NOT_APPLIED, CsSnrControl::NOT_APPLIED),
handler_->BindOnceOn(this, &impl::on_cs_set_procedure_parameters));
}
static void reset_tracker_on_stopped(CsTracker& cs_tracker) {
cs_tracker.measurement_ongoing = false;
+ cs_tracker.state = CsTrackerState::STOPPED;
}
void handle_cs_setup_failure(uint16_t connection_handle, DistanceMeasurementErrorCode errorCode) {
@@ -644,12 +682,21 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
return;
}
- if (!it->second.measurement_ongoing) {
- log::error("safe guard, error state, no local measurement request.");
- if (it->second.repeating_alarm) {
- it->second.repeating_alarm->Cancel();
+ if (enable == Enable::ENABLED) {
+ if (it->second.state == CsTrackerState::STOPPED) {
+ log::error("safe guard, error state, no local measurement request.");
+ if (it->second.repeating_alarm) {
+ it->second.repeating_alarm->Cancel();
+ }
+ return;
+ }
+ it->second.state = CsTrackerState::WAIT_FOR_PROCEDURE_ENABLED;
+ } else { // Enable::DISABLE
+ if (it->second.state != CsTrackerState::WAIT_FOR_PROCEDURE_ENABLED &&
+ it->second.state != CsTrackerState::STARTED) {
+ log::info("no procedure disable command needed for state {}.", (int)it->second.state);
+ return;
}
- return;
}
hci_layer_->EnqueueCommand(
@@ -694,6 +741,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
return;
}
cs_subfeature_supported_ = complete_view.GetOptionalSubfeaturesSupported();
+ num_antennas_supported_ = complete_view.GetNumAntennasSupported();
}
void on_cs_read_remote_supported_capabilities_complete(
@@ -721,9 +769,11 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
if (req_it != cs_requester_trackers_.end() && req_it->second.measurement_ongoing) {
req_it->second.remote_support_phase_based_ranging =
event_view.GetOptionalSubfeaturesSupported().phase_based_ranging_ == 0x01;
+ req_it->second.remote_num_antennas_supported_ = event_view.GetNumAntennasSupported();
req_it->second.setup_complete = true;
log::info("Setup phase complete, connection_handle: {}, address: {}", connection_handle,
cs_requester_trackers_[connection_handle].address);
+ req_it->second.retry_counter_for_create_config = 0;
send_le_cs_create_config(connection_handle,
cs_requester_trackers_[connection_handle].config_id);
}
@@ -762,11 +812,18 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
handle_cs_setup_failure(connection_handle, REASON_INTERNAL_ERROR);
return;
}
- auto it = cs_requester_trackers_.find(connection_handle);
- if (it != cs_requester_trackers_.end() && it->second.measurement_ongoing &&
- !it->second.config_set) {
- it->second.config_set = true;
- send_le_cs_set_procedure_parameters(event_view.GetConnectionHandle(), it->second.config_id);
+ auto req_it = cs_requester_trackers_.find(connection_handle);
+ if (req_it != cs_requester_trackers_.end() && req_it->second.measurement_ongoing &&
+ !req_it->second.config_set) {
+ req_it->second.config_set = true;
+ send_le_cs_set_procedure_parameters(event_view.GetConnectionHandle(),
+ req_it->second.config_id,
+ req_it->second.remote_num_antennas_supported_);
+ }
+ auto res_it = cs_responder_trackers_.find(connection_handle);
+ if (res_it != cs_responder_trackers_.end() &&
+ res_it->second.state == CsTrackerState::WAIT_FOR_SECURITY_ENABLED) {
+ res_it->second.state = CsTrackerState::WAIT_FOR_PROCEDURE_ENABLED;
}
}
@@ -779,11 +836,31 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
if (event_view.GetStatus() != ErrorCode::SUCCESS) {
std::string error_code = ErrorCodeText(event_view.GetStatus());
log::warn("Received LeCsConfigCompleteView with error code {}", error_code);
- handle_cs_setup_failure(connection_handle, REASON_INTERNAL_ERROR);
+ // The Create Config LL packet may arrive before the remote side has finished setting default
+ // settings, which will result in create config failure. Retry to ensure the remote side has
+ // completed its setup.
+ if (cs_requester_trackers_.find(connection_handle) != cs_requester_trackers_.end() &&
+ cs_requester_trackers_[connection_handle].retry_counter_for_create_config <
+ kMaxRetryCounterForCreateConfig) {
+ cs_requester_trackers_[connection_handle].retry_counter_for_create_config++;
+ log::info("send_le_cs_create_config, retry counter {}",
+ cs_requester_trackers_[connection_handle].retry_counter_for_create_config);
+ send_le_cs_create_config(connection_handle,
+ cs_requester_trackers_[connection_handle].config_id);
+ } else {
+ handle_cs_setup_failure(connection_handle, REASON_INTERNAL_ERROR);
+ }
return;
}
uint8_t config_id = event_view.GetConfigId();
- CsTracker* live_tracker = get_live_tracker(connection_handle, config_id);
+ check_and_handle_conflict(connection_handle, config_id,
+ CsTrackerState::WAIT_FOR_CONFIG_COMPLETE);
+ uint8_t valid_requester_states = static_cast<uint8_t>(CsTrackerState::WAIT_FOR_CONFIG_COMPLETE);
+ // any state, as the remote can start over at any time.
+ uint8_t valid_responder_states = static_cast<uint8_t>(CsTrackerState::UNSPECIFIED);
+
+ CsTracker* live_tracker = get_live_tracker(connection_handle, config_id, valid_requester_states,
+ valid_responder_states);
if (live_tracker == nullptr) {
log::warn("Can't find cs tracker for connection_handle {}", connection_handle);
return;
@@ -802,6 +879,10 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
// send the cmd from the BLE central only.
send_le_cs_security_enable(connection_handle);
}
+ // TODO: else set a timeout alarm to make sure the remote would trigger the cmd.
+ if (!live_tracker->local_start) {
+ live_tracker->state = CsTrackerState::WAIT_FOR_SECURITY_ENABLED;
+ }
}
void on_cs_set_procedure_parameters(CommandCompleteView view) {
@@ -834,24 +915,53 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
}
}
- CsTracker* get_live_tracker(uint16_t connection_handle, uint8_t config_id) {
- // suppose the config_id is unique, otherwise, no way to know if the event from controller
- // is from local(requester) or remote(responder).
+ CsTracker* get_live_tracker(uint16_t connection_handle, uint8_t config_id,
+ uint8_t valid_requester_states, uint8_t valid_responder_states) {
// CAVEAT: if the remote is sending request with the same config id, the behavior is undefined.
- auto it = cs_requester_trackers_.find(connection_handle);
- if (it != cs_requester_trackers_.end() && it->second.measurement_ongoing &&
- it->second.config_id == config_id) {
- return &(it->second);
+ auto req_it = cs_requester_trackers_.find(connection_handle);
+ if (req_it != cs_requester_trackers_.end() && req_it->second.state != CsTrackerState::STOPPED &&
+ req_it->second.config_id == config_id &&
+ (valid_requester_states & static_cast<uint8_t>(req_it->second.state)) != 0) {
+ return &cs_requester_trackers_[connection_handle];
}
- // take it as responder any way
- if (cs_responder_trackers_.find(connection_handle) != cs_responder_trackers_.end()) {
+
+ auto res_it = cs_responder_trackers_.find(connection_handle);
+ if (res_it != cs_responder_trackers_.end() &&
+ (res_it->second.config_id == kInvalidConfigId || res_it->second.config_id == config_id) &&
+ (valid_responder_states == static_cast<uint8_t>(CsTrackerState::UNSPECIFIED) ||
+ (valid_responder_states & static_cast<uint8_t>(res_it->second.state)) != 0)) {
return &cs_responder_trackers_[connection_handle];
}
-
- log::error("no event is expected as no any live cs tracker for {}", connection_handle);
+ log::error("no valid tracker to handle the event.");
return nullptr;
}
+ void check_and_handle_conflict(uint16_t connection_handle, uint8_t event_config_id,
+ CsTrackerState expected_requester_state) {
+ // If the local and remote were triggering the event at the same time, and the controller
+ // allows that happen, the things may still get messed; If the spec can differentiate the
+ // local event or remote event, that would be clearer.
+ auto it = cs_requester_trackers_.find(connection_handle);
+ if (it == cs_requester_trackers_.end()) {
+ return;
+ }
+ if (event_config_id != it->second.config_id) {
+ return;
+ }
+ if (it->second.state == expected_requester_state) {
+ return;
+ }
+ log::warn("unexpected request from remote, which is conflict with the local measurement.");
+ it->second.config_set = false;
+ if (it->second.state != CsTrackerState::STOPPED) {
+ stop_distance_measurement(it->second.address, connection_handle,
+ DistanceMeasurementMethod::METHOD_CS);
+ // TODO: clean up the stopped callback, it should be called within stop_distance_measurement.
+ distance_measurement_callbacks_->OnDistanceMeasurementStopped(
+ it->second.address, REASON_REMOTE_REQUEST, METHOD_CS);
+ }
+ }
+
void on_cs_procedure_enable_complete(LeCsProcedureEnableCompleteView event_view) {
log::assert_that(event_view.IsValid(), "assert failed: event_view.IsValid()");
uint16_t connection_handle = event_view.GetConnectionHandle();
@@ -863,13 +973,26 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
return;
}
uint8_t config_id = event_view.GetConfigId();
- CsTracker* live_tracker = get_live_tracker(connection_handle, config_id);
- if (live_tracker == nullptr) {
- log::error("no tracker is available for {}", connection_handle);
- return;
- }
+
+ CsTracker* live_tracker = nullptr;
if (event_view.GetState() == Enable::ENABLED) {
+ check_and_handle_conflict(connection_handle, config_id,
+ CsTrackerState::WAIT_FOR_PROCEDURE_ENABLED);
+ uint8_t valid_requester_states =
+ static_cast<uint8_t>(CsTrackerState::WAIT_FOR_PROCEDURE_ENABLED);
+ uint8_t valid_responder_states =
+ static_cast<uint8_t>(CsTrackerState::STOPPED) |
+ static_cast<uint8_t>(CsTrackerState::INIT) |
+ static_cast<uint8_t>(CsTrackerState::STARTED) |
+ static_cast<uint8_t>(CsTrackerState::WAIT_FOR_PROCEDURE_ENABLED);
+ live_tracker = get_live_tracker(connection_handle, config_id, valid_requester_states,
+ valid_responder_states);
+ if (live_tracker == nullptr) {
+ log::error("no tracker is available for {}", connection_handle);
+ return;
+ }
log::debug("Procedure enabled, {}", event_view.ToString());
+ live_tracker->state = CsTrackerState::STARTED;
// assign the config_id, as this is may be the 1st time to get it for responder;
live_tracker->config_id = config_id;
live_tracker->selected_tx_power = event_view.GetSelectedTxPower();
@@ -880,15 +1003,15 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
distance_measurement_callbacks_->OnDistanceMeasurementStarted(live_tracker->address,
METHOD_CS);
}
- // cs role switch from requester to responder, may reset the config if conflict.
- if (!live_tracker->local_start &&
- cs_requester_trackers_.find(connection_handle) != cs_requester_trackers_.end() &&
- cs_requester_trackers_[connection_handle].config_id == live_tracker->config_id) {
- log::debug("config id {} from remote is the same as the cached local, reset config_set.",
- cs_requester_trackers_[connection_handle].config_id);
- cs_requester_trackers_[connection_handle].config_set = false;
- }
} else if (event_view.GetState() == Enable::DISABLED) {
+ uint8_t valid_requester_states = static_cast<uint8_t>(CsTrackerState::STARTED);
+ uint8_t valid_responder_states = static_cast<uint8_t>(CsTrackerState::STARTED);
+ live_tracker = get_live_tracker(connection_handle, config_id, valid_requester_states,
+ valid_responder_states);
+ if (live_tracker == nullptr) {
+ log::error("no tracker is available for {}", connection_handle);
+ return;
+ }
reset_tracker_on_stopped(*live_tracker);
}
// reset the procedure data list.
@@ -912,6 +1035,8 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
SubeventAbortReason subevent_abort_reason;
std::vector<LeCsResultDataStructure> result_data_structures;
CsTracker* live_tracker = nullptr;
+ uint8_t valid_requester_states = static_cast<uint8_t>(CsTrackerState::STARTED);
+ uint8_t valid_responder_states = static_cast<uint8_t>(CsTrackerState::STARTED);
if (event.GetSubeventCode() == SubeventCode::LE_CS_SUBEVENT_RESULT) {
auto cs_event_result = LeCsSubeventResultView::Create(event);
if (!cs_event_result.IsValid()) {
@@ -919,7 +1044,8 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
return;
}
connection_handle = cs_event_result.GetConnectionHandle();
- live_tracker = get_live_tracker(connection_handle, cs_event_result.GetConfigId());
+ live_tracker = get_live_tracker(connection_handle, cs_event_result.GetConfigId(),
+ valid_requester_states, valid_responder_states);
if (live_tracker == nullptr) {
log::error("no live tracker is available for {}", connection_handle);
return;
@@ -951,7 +1077,8 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
return;
}
connection_handle = cs_event_result.GetConnectionHandle();
- live_tracker = get_live_tracker(connection_handle, cs_event_result.GetConfigId());
+ live_tracker = get_live_tracker(connection_handle, cs_event_result.GetConfigId(),
+ valid_requester_states, valid_responder_states);
procedure_done_status = cs_event_result.GetProcedureDoneStatus();
subevent_done_status = cs_event_result.GetSubeventDoneStatus();
procedure_abort_reason = cs_event_result.GetProcedureAbortReason();
@@ -1074,6 +1201,10 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
log::warn("can't find tracker for 0x{:04x}", connection_handle);
return;
}
+ if (cs_requester_trackers_[connection_handle].state != CsTrackerState::STARTED) {
+ log::warn("The measurement for {} is stopped, ignore the remote data.", connection_handle);
+ return;
+ }
auto& tracker = cs_requester_trackers_[connection_handle];
SegmentationHeader segmentation_header;
@@ -1648,6 +1779,13 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
std::unordered_map<uint16_t, CsTracker> cs_responder_trackers_;
DistanceMeasurementCallbacks* distance_measurement_callbacks_;
CsOptionalSubfeaturesSupported cs_subfeature_supported_;
+ uint8_t num_antennas_supported_ = 0x01;
+ // A table that maps num_antennas_supported and remote_num_antennas_supported to Antenna
+ // Configuration Index.
+ uint8_t cs_tone_antenna_config_mapping_table_[4][4] = {
+ {0, 4, 5, 6}, {1, 7, 7, 7}, {2, 7, 7, 7}, {3, 7, 7, 7}};
+ // A table that maps Antenna Configuration Index to Preferred Peer Antenna.
+ uint8_t cs_preferred_peer_antenna_mapping_table_[8] = {1, 1, 1, 1, 3, 7, 15, 3};
// Antenna path permutations. See Channel Sounding CR_PR for the details.
uint8_t cs_antenna_permutation_array_[24][4] = {
{1, 2, 3, 4}, {2, 1, 3, 4}, {1, 3, 2, 4}, {3, 1, 2, 4}, {3, 2, 1, 4}, {2, 3, 1, 4},
diff --git a/system/gd/hci/event_checkers.h b/system/gd/hci/event_checkers.h
index 41aca0718f..a484f5752e 100644
--- a/system/gd/hci/event_checkers.h
+++ b/system/gd/hci/event_checkers.h
@@ -19,7 +19,6 @@
#include <bluetooth/log.h>
#include "hci/hci_packets.h"
-#include "os/log.h"
namespace bluetooth {
namespace hci {
diff --git a/system/gd/hci/facade/le_advertising_manager_facade.cc b/system/gd/hci/facade/le_advertising_manager_facade.cc
index 43b68aedf5..d9c6cca0d8 100644
--- a/system/gd/hci/facade/le_advertising_manager_facade.cc
+++ b/system/gd/hci/facade/le_advertising_manager_facade.cc
@@ -31,7 +31,6 @@
#include "hci/address.h"
#include "hci/address_with_type.h"
#include "hci/le_advertising_manager.h"
-#include "os/log.h"
// TODO(b/369381361) Enfore -Wmissing-prototypes
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
diff --git a/system/gd/hci/facade/le_scanning_manager_facade.cc b/system/gd/hci/facade/le_scanning_manager_facade.cc
index 8a2e7f90ee..243b46ff4e 100644
--- a/system/gd/hci/facade/le_scanning_manager_facade.cc
+++ b/system/gd/hci/facade/le_scanning_manager_facade.cc
@@ -28,7 +28,6 @@
#include "common/bind.h"
#include "grpc/grpc_event_queue.h"
#include "hci/le_scanning_manager.h"
-#include "os/log.h"
#include "packet/raw_builder.h"
namespace bluetooth {
diff --git a/system/gd/hci/fuzz/acl_manager_fuzz_test.cc b/system/gd/hci/fuzz/acl_manager_fuzz_test.cc
index 527982ced5..06544789b7 100644
--- a/system/gd/hci/fuzz/acl_manager_fuzz_test.cc
+++ b/system/gd/hci/fuzz/acl_manager_fuzz_test.cc
@@ -24,7 +24,6 @@
#include "hci/hci_layer.h"
#include "module.h"
#include "os/fake_timer/fake_timerfd.h"
-#include "os/log.h"
// TODO(b/369381361) Enfore -Wmissing-prototypes
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
diff --git a/system/gd/hci/fuzz/fuzz_hci_layer.h b/system/gd/hci/fuzz/fuzz_hci_layer.h
index 07a58fdc74..10492cdda9 100644
--- a/system/gd/hci/fuzz/fuzz_hci_layer.h
+++ b/system/gd/hci/fuzz/fuzz_hci_layer.h
@@ -26,7 +26,6 @@
#include "hci/hci_layer.h"
#include "os/fuzz/dev_null_queue.h"
#include "os/fuzz/fuzz_inject_queue.h"
-#include "os/log.h"
namespace bluetooth {
namespace hci {
diff --git a/system/gd/hci/fuzz/hci_layer_fuzz_test.cc b/system/gd/hci/fuzz/hci_layer_fuzz_test.cc
index 48191efe1c..392ffdd3e6 100644
--- a/system/gd/hci/fuzz/hci_layer_fuzz_test.cc
+++ b/system/gd/hci/fuzz/hci_layer_fuzz_test.cc
@@ -24,7 +24,6 @@
#include "hci/hci_layer.h"
#include "module.h"
#include "os/fake_timer/fake_timerfd.h"
-#include "os/log.h"
// TODO(b/369381361) Enfore -Wmissing-prototypes
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
diff --git a/system/gd/hci/hci_layer.cc b/system/gd/hci/hci_layer.cc
index 70a5f43b56..f9847101c0 100644
--- a/system/gd/hci/hci_layer.cc
+++ b/system/gd/hci/hci_layer.cc
@@ -279,6 +279,17 @@ struct HciLayer::impl {
command_queue_.clear();
command_credits_ = 1;
waiting_command_ = OpCode::NONE;
+
+#ifdef TARGET_FLOSS
+ log::warn("Ignoring the timeouted HCI command {}.", OpCodeText(op_code));
+ // Terminate the process to trigger controller reset, also mark the controller
+ // is broken to prevent further error while terminating.
+ auto hal = module_.GetDependency<hal::HciHal>();
+ hal->markControllerBroken();
+ kill(getpid(), SIGTERM);
+ return;
+#endif
+
// Ignore the response, since we don't know what might come back.
enqueue_command(ControllerDebugInfoBuilder::Create(),
module_.GetHandler()->BindOnce([](CommandCompleteView) {}));
diff --git a/system/gd/hci/hci_layer_test.cc b/system/gd/hci/hci_layer_test.cc
index 9f8d9ead3c..1f677d518b 100644
--- a/system/gd/hci/hci_layer_test.cc
+++ b/system/gd/hci/hci_layer_test.cc
@@ -24,7 +24,6 @@
#include "hal/hci_hal_fake.h"
#include "hci/hci_packets.h"
#include "module.h"
-#include "os/log.h"
#include "os/thread.h"
#include "packet/bit_inserter.h"
#include "packet/raw_builder.h"
diff --git a/system/gd/hci/hci_packets_fuzz_test.cc b/system/gd/hci/hci_packets_fuzz_test.cc
index 68ebf7e6da..2868477c46 100644
--- a/system/gd/hci/hci_packets_fuzz_test.cc
+++ b/system/gd/hci/hci_packets_fuzz_test.cc
@@ -18,7 +18,6 @@
#include <memory>
#include "hci/hci_packets.h"
-#include "os/log.h"
#include "packet/bit_inserter.h"
#include "packet/raw_builder.h"
diff --git a/system/gd/hci/hci_packets_test.cc b/system/gd/hci/hci_packets_test.cc
index 9df54187bb..01121c7922 100644
--- a/system/gd/hci/hci_packets_test.cc
+++ b/system/gd/hci/hci_packets_test.cc
@@ -20,7 +20,6 @@
#define PACKET_TESTING // Instantiate the tests in the packet files
#include "hci/hci_packets.h"
-#include "os/log.h"
#include "packet/bit_inserter.h"
#include "packet/raw_builder.h"
diff --git a/system/gd/hci/le_scanning_manager.cc b/system/gd/hci/le_scanning_manager.cc
index 4ade641f93..6c9e9744b4 100644
--- a/system/gd/hci/le_scanning_manager.cc
+++ b/system/gd/hci/le_scanning_manager.cc
@@ -31,7 +31,6 @@
#include "hci/le_scanning_reassembler.h"
#include "module.h"
#include "os/handler.h"
-#include "os/log.h"
#include "os/system_properties.h"
#include "storage/storage_module.h"
diff --git a/system/gd/hci/le_scanning_reassembler.cc b/system/gd/hci/le_scanning_reassembler.cc
index c3199221a3..8f8ad06b00 100644
--- a/system/gd/hci/le_scanning_reassembler.cc
+++ b/system/gd/hci/le_scanning_reassembler.cc
@@ -28,7 +28,6 @@
#include "hci/le_scanning_interface.h"
#include "module.h"
#include "os/handler.h"
-#include "os/log.h"
#include "storage/storage_module.h"
namespace bluetooth::hci {
diff --git a/system/gd/metrics/chromeos/metrics.cc b/system/gd/metrics/chromeos/metrics.cc
index fbe7afcba3..9a7541735a 100644
--- a/system/gd/metrics/chromeos/metrics.cc
+++ b/system/gd/metrics/chromeos/metrics.cc
@@ -24,7 +24,6 @@
#include "metrics/chromeos/metrics_allowlist.h"
#include "metrics/chromeos/metrics_event.h"
#include "metrics/utils.h"
-#include "os/log.h"
namespace bluetooth {
namespace metrics {
diff --git a/system/gd/metrics/counter_metrics.cc b/system/gd/metrics/counter_metrics.cc
index 0155eb1bd0..1315a87df1 100644
--- a/system/gd/metrics/counter_metrics.cc
+++ b/system/gd/metrics/counter_metrics.cc
@@ -20,7 +20,6 @@
#include <bluetooth/log.h>
#include "common/bind.h"
-#include "os/log.h"
#include "os/metrics.h"
namespace bluetooth {
diff --git a/system/gd/module.h b/system/gd/module.h
index 14c81ccaf4..44aa0bcb29 100644
--- a/system/gd/module.h
+++ b/system/gd/module.h
@@ -30,7 +30,6 @@
#include "common/bind.h"
#include "os/handler.h"
-#include "os/log.h"
#include "os/thread.h"
namespace bluetooth {
diff --git a/system/gd/neighbor/name_db.cc b/system/gd/neighbor/name_db.cc
index 99eca8d0e1..48cdae4705 100644
--- a/system/gd/neighbor/name_db.cc
+++ b/system/gd/neighbor/name_db.cc
@@ -28,7 +28,6 @@
#include "hci/remote_name_request.h"
#include "module.h"
#include "os/handler.h"
-#include "os/log.h"
namespace bluetooth {
namespace neighbor {
diff --git a/system/gd/neighbor/scan.cc b/system/gd/neighbor/scan.cc
index fafb316b33..8559f338da 100644
--- a/system/gd/neighbor/scan.cc
+++ b/system/gd/neighbor/scan.cc
@@ -25,7 +25,6 @@
#include "hci/hci_packets.h"
#include "module.h"
#include "os/handler.h"
-#include "os/log.h"
namespace bluetooth {
namespace neighbor {
diff --git a/system/gd/os/android/metrics.cc b/system/gd/os/android/metrics.cc
index daea83d0a5..0a2dbd92b6 100644
--- a/system/gd/os/android/metrics.cc
+++ b/system/gd/os/android/metrics.cc
@@ -30,7 +30,6 @@
#include "common/strings.h"
#include "hardware/bt_av.h"
#include "hci/hci_packets.h"
-#include "os/log.h"
namespace fmt {
template <>
diff --git a/system/gd/os/android/system_properties.cc b/system/gd/os/android/system_properties.cc
index d7dc9e918a..d0f2707173 100644
--- a/system/gd/os/android/system_properties.cc
+++ b/system/gd/os/android/system_properties.cc
@@ -23,7 +23,6 @@
#include <cctype>
#include "common/strings.h"
-#include "os/log.h"
namespace bluetooth {
namespace os {
diff --git a/system/gd/os/android/wakelock_native.cc b/system/gd/os/android/wakelock_native.cc
index d34fa94cab..bc7d2ae130 100644
--- a/system/gd/os/android/wakelock_native.cc
+++ b/system/gd/os/android/wakelock_native.cc
@@ -32,20 +32,6 @@
#include <functional>
#include <string>
-// We want the os/log.h definitions
-#undef LOG_DEBUG
-#undef LOG_INFO
-
-#include "os/log.h"
-
-// Save the os/log.h definitions
-#pragma push_macro("LOG_DEBUG")
-#pragma push_macro("LOG_INFO")
-
-// Undef these to avoid conflicting with later imports
-#undef LOG_DEBUG
-#undef LOG_INFO
-
using ::aidl::android::system::suspend::ISystemSuspend;
using ::aidl::android::system::suspend::IWakeLock;
using ::aidl::android::system::suspend::WakeLockType;
@@ -54,10 +40,6 @@ namespace bluetooth {
namespace os {
namespace internal {
-// Restore the os/log.h definitions after all imported headers
-#pragma pop_macro("LOG_DEBUG")
-#pragma pop_macro("LOG_INFO")
-
static void onSuspendDeath(void* cookie) {
auto onDeath = static_cast<std::function<void(void)>*>(cookie);
(*onDeath)();
diff --git a/system/gd/os/chromeos/metrics.cc b/system/gd/os/chromeos/metrics.cc
index 2ec46c8c55..b3795341f2 100644
--- a/system/gd/os/chromeos/metrics.cc
+++ b/system/gd/os/chromeos/metrics.cc
@@ -22,7 +22,6 @@
#include <metrics/structured_events.h>
#include "metrics/utils.h"
-#include "os/log.h"
namespace bluetooth {
namespace os {
diff --git a/system/gd/os/chromeos/parameter_provider.cc b/system/gd/os/chromeos/parameter_provider.cc
index 2302a68e11..a8ee19c5a6 100644
--- a/system/gd/os/chromeos/parameter_provider.cc
+++ b/system/gd/os/chromeos/parameter_provider.cc
@@ -22,8 +22,6 @@
#include <mutex>
#include <string>
-#include "os/log.h"
-
namespace bluetooth {
namespace os {
diff --git a/system/gd/os/chromeos/wakelock_native.cc b/system/gd/os/chromeos/wakelock_native.cc
index 8cf7f71fde..33c84d45b5 100644
--- a/system/gd/os/chromeos/wakelock_native.cc
+++ b/system/gd/os/chromeos/wakelock_native.cc
@@ -22,8 +22,6 @@
#include <bluetooth/log.h>
-#include "os/log.h"
-
namespace bluetooth {
namespace os {
namespace internal {
diff --git a/system/gd/os/handler.cc b/system/gd/os/handler.cc
index f49236fde3..388fcd4c72 100644
--- a/system/gd/os/handler.cc
+++ b/system/gd/os/handler.cc
@@ -20,7 +20,6 @@
#include "common/bind.h"
#include "common/callback.h"
-#include "os/log.h"
#include "os/reactor.h"
namespace bluetooth {
diff --git a/system/gd/os/handler_unittest.cc b/system/gd/os/handler_unittest.cc
index 0a06699c39..7306effd30 100644
--- a/system/gd/os/handler_unittest.cc
+++ b/system/gd/os/handler_unittest.cc
@@ -22,7 +22,6 @@
#include "common/bind.h"
#include "common/callback.h"
#include "gtest/gtest.h"
-#include "os/log.h"
namespace bluetooth {
namespace os {
diff --git a/system/gd/os/host/metrics.cc b/system/gd/os/host/metrics.cc
index 27e5d7d470..a019033348 100644
--- a/system/gd/os/host/metrics.cc
+++ b/system/gd/os/host/metrics.cc
@@ -18,8 +18,6 @@
#include "os/metrics.h"
-#include "os/log.h"
-
namespace bluetooth {
namespace os {
diff --git a/system/gd/os/host/parameter_provider.cc b/system/gd/os/host/parameter_provider.cc
index 37d6232ebe..7b150da4be 100644
--- a/system/gd/os/host/parameter_provider.cc
+++ b/system/gd/os/host/parameter_provider.cc
@@ -23,8 +23,6 @@
#include <mutex>
#include <string>
-#include "os/log.h"
-
namespace bluetooth {
namespace os {
diff --git a/system/gd/os/host/wakelock_native.cc b/system/gd/os/host/wakelock_native.cc
index d09d91fbf3..dd8026d007 100644
--- a/system/gd/os/host/wakelock_native.cc
+++ b/system/gd/os/host/wakelock_native.cc
@@ -22,8 +22,6 @@
#include <bluetooth/log.h>
-#include "os/log.h"
-
namespace bluetooth {
namespace os {
namespace internal {
diff --git a/system/gd/os/linux/metrics.cc b/system/gd/os/linux/metrics.cc
index df3a413eee..c5e38493da 100644
--- a/system/gd/os/linux/metrics.cc
+++ b/system/gd/os/linux/metrics.cc
@@ -18,8 +18,6 @@
#include "os/metrics.h"
-#include "os/log.h"
-
namespace bluetooth {
namespace os {
diff --git a/system/gd/os/linux/parameter_provider.cc b/system/gd/os/linux/parameter_provider.cc
index 2302a68e11..a8ee19c5a6 100644
--- a/system/gd/os/linux/parameter_provider.cc
+++ b/system/gd/os/linux/parameter_provider.cc
@@ -22,8 +22,6 @@
#include <mutex>
#include <string>
-#include "os/log.h"
-
namespace bluetooth {
namespace os {
diff --git a/system/gd/os/linux/wakelock_native.cc b/system/gd/os/linux/wakelock_native.cc
index 8cf7f71fde..33c84d45b5 100644
--- a/system/gd/os/linux/wakelock_native.cc
+++ b/system/gd/os/linux/wakelock_native.cc
@@ -22,8 +22,6 @@
#include <bluetooth/log.h>
-#include "os/log.h"
-
namespace bluetooth {
namespace os {
namespace internal {
diff --git a/system/gd/os/linux_generic/alarm.cc b/system/gd/os/linux_generic/alarm.cc
index 971b595dbc..46c06e5d26 100644
--- a/system/gd/os/linux_generic/alarm.cc
+++ b/system/gd/os/linux_generic/alarm.cc
@@ -25,7 +25,6 @@
#include "common/bind.h"
#include "os/linux_generic/linux.h"
-#include "os/log.h"
#include "os/utils.h"
#ifdef __ANDROID__
diff --git a/system/gd/os/linux_generic/files.cc b/system/gd/os/linux_generic/files.cc
index 38896cccc7..a759e1d631 100644
--- a/system/gd/os/linux_generic/files.cc
+++ b/system/gd/os/linux_generic/files.cc
@@ -28,8 +28,6 @@
#include <streambuf>
#include <string>
-#include "os/log.h"
-
namespace {
void HandleError(const std::string& temp_path, int* dir_fd, FILE** fp) {
diff --git a/system/gd/os/linux_generic/reactive_semaphore.cc b/system/gd/os/linux_generic/reactive_semaphore.cc
index 47d1ee9406..57fc9d6fe9 100644
--- a/system/gd/os/linux_generic/reactive_semaphore.cc
+++ b/system/gd/os/linux_generic/reactive_semaphore.cc
@@ -24,7 +24,6 @@
#include <functional>
#include "os/linux_generic/linux.h"
-#include "os/log.h"
namespace bluetooth {
namespace os {
diff --git a/system/gd/os/linux_generic/reactor.cc b/system/gd/os/linux_generic/reactor.cc
index 58a5f93a11..4fc2ac92b3 100644
--- a/system/gd/os/linux_generic/reactor.cc
+++ b/system/gd/os/linux_generic/reactor.cc
@@ -27,8 +27,6 @@
#include <cinttypes>
#include <cstring>
-#include "os/log.h"
-
namespace {
// Use at most sizeof(epoll_event) * kEpollMaxEvents kernel memory
diff --git a/system/gd/os/linux_generic/reactor_unittest.cc b/system/gd/os/linux_generic/reactor_unittest.cc
index de6b829a67..d131f5f74d 100644
--- a/system/gd/os/linux_generic/reactor_unittest.cc
+++ b/system/gd/os/linux_generic/reactor_unittest.cc
@@ -26,7 +26,6 @@
#include "common/bind.h"
#include "common/callback.h"
#include "gtest/gtest.h"
-#include "os/log.h"
namespace bluetooth {
namespace os {
diff --git a/system/gd/os/linux_generic/repeating_alarm.cc b/system/gd/os/linux_generic/repeating_alarm.cc
index f62de8be65..20542228d4 100644
--- a/system/gd/os/linux_generic/repeating_alarm.cc
+++ b/system/gd/os/linux_generic/repeating_alarm.cc
@@ -24,7 +24,6 @@
#include "common/bind.h"
#include "os/linux_generic/linux.h"
-#include "os/log.h"
#include "os/utils.h"
#ifdef __ANDROID__
diff --git a/system/gd/os/linux_generic/thread.cc b/system/gd/os/linux_generic/thread.cc
index 9bc2e496b1..33dfb2a229 100644
--- a/system/gd/os/linux_generic/thread.cc
+++ b/system/gd/os/linux_generic/thread.cc
@@ -24,8 +24,6 @@
#include <cerrno>
#include <cstring>
-#include "os/log.h"
-
namespace bluetooth {
namespace os {
diff --git a/system/gd/os/linux_generic/wakelock_manager.cc b/system/gd/os/linux_generic/wakelock_manager.cc
index 022904c942..b8cc9000ba 100644
--- a/system/gd/os/linux_generic/wakelock_manager.cc
+++ b/system/gd/os/linux_generic/wakelock_manager.cc
@@ -26,7 +26,6 @@
#include <mutex>
#include "os/internal/wakelock_native.h"
-#include "os/log.h"
// TODO(b/369381361) Enfore -Wmissing-prototypes
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
diff --git a/system/gd/os/log.h b/system/gd/os/log.h
deleted file mode 100644
index 456fbe3f0d..0000000000
--- a/system/gd/os/log.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2019 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.
- *
- ******************************************************************************/
-
-#pragma once
-
-#include <inttypes.h>
-
-#include <cstdlib>
-
-#include "os/logging/log_adapter.h"
-
-#if defined(__ANDROID__)
-#include <log/log.h>
-#include <log/log_event_list.h>
-#endif // defined(__ANDROID__)
diff --git a/system/gd/os/mock_queue.h b/system/gd/os/mock_queue.h
index 41aa743e9c..03ede2025b 100644
--- a/system/gd/os/mock_queue.h
+++ b/system/gd/os/mock_queue.h
@@ -26,7 +26,6 @@
#include "common/bind.h"
#include "common/callback.h"
#include "os/handler.h"
-#include "os/log.h"
#include "os/queue.h"
namespace bluetooth {
diff --git a/system/gd/os/queue.h b/system/gd/os/queue.h
index d722c33a4a..fef9073202 100644
--- a/system/gd/os/queue.h
+++ b/system/gd/os/queue.h
@@ -27,7 +27,6 @@
#include "common/callback.h"
#include "os/handler.h"
#include "os/linux_generic/reactive_semaphore.h"
-#include "os/log.h"
namespace bluetooth {
namespace os {
diff --git a/system/gd/os/rand.h b/system/gd/os/rand.h
index edda493b31..e2b0b649fd 100644
--- a/system/gd/os/rand.h
+++ b/system/gd/os/rand.h
@@ -22,8 +22,6 @@
#include <array>
#include <cstdint>
-#include "os/log.h"
-
namespace bluetooth {
namespace os {
diff --git a/system/gd/packet/Android.bp b/system/gd/packet/Android.bp
index 851afb6ccf..c4504a62c8 100644
--- a/system/gd/packet/Android.bp
+++ b/system/gd/packet/Android.bp
@@ -19,7 +19,10 @@ filegroup {
"raw_builder.cc",
"view.cc",
],
- visibility: ["//visibility:public"],
+ visibility: [
+ "//hardware/interfaces/bluetooth/aidl/vts",
+ "//packages/modules/Bluetooth/system:__subpackages__",
+ ],
}
filegroup {
diff --git a/system/gd/packet/bit_inserter_unittest.cc b/system/gd/packet/bit_inserter_unittest.cc
index 5c78db51ff..636fa470bd 100644
--- a/system/gd/packet/bit_inserter_unittest.cc
+++ b/system/gd/packet/bit_inserter_unittest.cc
@@ -20,8 +20,6 @@
#include <memory>
-#include "os/log.h"
-
using bluetooth::packet::BitInserter;
using std::vector;
diff --git a/system/gd/packet/fragmenting_inserter_unittest.cc b/system/gd/packet/fragmenting_inserter_unittest.cc
index dee70a615c..5d90a5a075 100644
--- a/system/gd/packet/fragmenting_inserter_unittest.cc
+++ b/system/gd/packet/fragmenting_inserter_unittest.cc
@@ -20,8 +20,6 @@
#include <memory>
-#include "os/log.h"
-
using bluetooth::packet::FragmentingInserter;
using std::vector;
diff --git a/system/gd/packet/packet_builder.h b/system/gd/packet/packet_builder.h
index e86af5289d..19a0be1183 100644
--- a/system/gd/packet/packet_builder.h
+++ b/system/gd/packet/packet_builder.h
@@ -22,7 +22,6 @@
#include <memory>
#include <vector>
-#include "os/log.h"
#include "packet/base_packet_builder.h"
#include "packet/bit_inserter.h"
#include "packet/endian_inserter.h"
diff --git a/system/gd/packet/packet_struct.h b/system/gd/packet/packet_struct.h
index 92e3200f35..92ab83e4db 100644
--- a/system/gd/packet/packet_struct.h
+++ b/system/gd/packet/packet_struct.h
@@ -22,7 +22,6 @@
#include <memory>
#include <vector>
-#include "os/log.h"
#include "packet/base_struct.h"
#include "packet/bit_inserter.h"
#include "packet/endian_inserter.h"
diff --git a/system/gd/packet/parser/test/generated_packet_test.cc b/system/gd/packet/parser/test/generated_packet_test.cc
index 66ca1fb7cc..e706e15bee 100644
--- a/system/gd/packet/parser/test/generated_packet_test.cc
+++ b/system/gd/packet/parser/test/generated_packet_test.cc
@@ -20,7 +20,7 @@
#include <memory>
#define PACKET_TESTING
-#include "os/log.h"
+
#include "packet/bit_inserter.h"
#include "packet/parser/test/big_endian_test_packets.h"
#include "packet/parser/test/six_bytes.h"
diff --git a/system/gd/packet/raw_builder.cc b/system/gd/packet/raw_builder.cc
index 604d3ee8a1..49ebeed351 100644
--- a/system/gd/packet/raw_builder.cc
+++ b/system/gd/packet/raw_builder.cc
@@ -19,8 +19,6 @@
#include <algorithm>
#include <utility>
-#include "os/log.h"
-
namespace bluetooth {
namespace packet {
diff --git a/system/gd/rust/linux/stack/src/battery_service.rs b/system/gd/rust/linux/stack/src/battery_service.rs
index 688d5fd3ca..013b941260 100644
--- a/system/gd/rust/linux/stack/src/battery_service.rs
+++ b/system/gd/rust/linux/stack/src/battery_service.rs
@@ -2,7 +2,6 @@ use crate::battery_manager::{Battery, BatterySet};
use crate::battery_provider_manager::{
BatteryProviderManager, IBatteryProviderCallback, IBatteryProviderManager,
};
-use crate::bluetooth::BluetoothDevice;
use crate::bluetooth_gatt::{
BluetoothGatt, BluetoothGattService, IBluetoothGatt, IBluetoothGattCallback,
};
@@ -10,9 +9,9 @@ use crate::callbacks::Callbacks;
use crate::Message;
use crate::RPCProxy;
use crate::{uuid, APIMessage, BluetoothAPI};
-use bt_topshim::btif::{BtAclState, BtBondState, BtTransport, DisplayAddress, RawAddress, Uuid};
+use bt_topshim::btif::{BtTransport, DisplayAddress, RawAddress, Uuid};
use bt_topshim::profiles::gatt::{GattStatus, LePhy};
-use log::debug;
+use log::{debug, info};
use std::collections::HashMap;
use std::convert::TryInto;
use std::iter;
@@ -23,6 +22,10 @@ use tokio::sync::mpsc::Sender;
/// specification.
pub const CHARACTERISTIC_BATTERY_LEVEL: &str = "00002A1-9000-0100-0800-000805F9B34FB";
+/// The app UUID BAS provides when connecting as a GATT client. Chosen at random.
+/// TODO(b/233101174): make dynamic or decide on a static UUID
+pub const BATTERY_SERVICE_GATT_CLIENT_APP_ID: &str = "e4d2acffcfaa42198f494606b7412117";
+
/// Represents the Floss BatteryService implementation.
pub struct BatteryService {
gatt: Arc<Mutex<Box<BluetoothGatt>>>,
@@ -55,10 +58,6 @@ pub enum BatteryServiceActions {
OnCharacteristicRead(RawAddress, GattStatus, i32, Vec<u8>),
/// Params: addr, handle, value
OnNotify(RawAddress, i32, Vec<u8>),
- /// Params: remote_device, transport
- Connect(BluetoothDevice, BtAclState, BtBondState, BtTransport),
- /// Params: remote_device
- Disconnect(BluetoothDevice),
}
/// API for Floss implementation of the Bluetooth Battery Service (BAS). BAS is built on GATT and
@@ -127,8 +126,7 @@ impl BatteryService {
pub fn init(&self) {
debug!("Registering GATT client for BatteryService");
self.gatt.lock().unwrap().register_client(
- // TODO(b/233101174): make dynamic or decide on a static UUID
- String::from("e4d2acffcfaa42198f494606b7412117"),
+ String::from(BATTERY_SERVICE_GATT_CLIENT_APP_ID),
Box::new(GattCallback::new(self.tx.clone(), self.api_tx.clone())),
false,
);
@@ -144,6 +142,13 @@ impl BatteryService {
BatteryServiceActions::OnClientConnectionState(status, _client_id, connected, addr) => {
if !connected || status != GattStatus::Success {
+ info!(
+ "BAS: Dropping {} due to GATT state changed: connected={}, status={:?}",
+ DisplayAddress(&addr),
+ connected,
+ status
+ );
+ self.drop_device(addr);
return;
}
let client_id = match self.client_id {
@@ -157,8 +162,8 @@ impl BatteryService {
BatteryServiceActions::OnSearchComplete(addr, services, status) => {
if status != GattStatus::Success {
- debug!(
- "GATT service discovery for {} failed with status {:?}",
+ info!(
+ "BAS: Service discovery for {} failed: status={:?}",
DisplayAddress(&addr),
status
);
@@ -176,10 +181,16 @@ impl BatteryService {
)
});
}
+ info!(
+ "BAS: Failed to get handle from {}: status={:?}",
+ DisplayAddress(&addr),
+ status
+ );
self.drop_device(addr);
return;
}
};
+ info!("BAS: Found handle from {}", DisplayAddress(&addr));
let client_id = match self.client_id {
Some(id) => id,
None => {
@@ -221,21 +232,6 @@ impl BatteryService {
callback.on_battery_info_updated(addr, battery_info.clone());
});
}
-
- BatteryServiceActions::Connect(device, acl_state, bond_state, transport) => {
- if transport != BtTransport::Le
- || acl_state != BtAclState::Connected
- || bond_state != BtBondState::Bonded
- {
- return;
- }
-
- self.init_device(device.address, transport);
- }
-
- BatteryServiceActions::Disconnect(device) => {
- self.drop_device(device.address);
- }
}
}
@@ -258,23 +254,22 @@ impl BatteryService {
battery_set.clone()
}
- fn init_device(&self, remote_address: RawAddress, transport: BtTransport) {
+ pub(crate) fn init_device(&self, remote_address: RawAddress) {
let client_id = match self.client_id {
Some(id) => id,
None => return,
};
- debug!("Attempting GATT connection to {}", DisplayAddress(&remote_address));
self.gatt.lock().unwrap().client_connect(
client_id,
remote_address,
false,
- transport,
+ BtTransport::Le,
false,
LePhy::Phy1m,
);
}
- fn drop_device(&mut self, remote_address: RawAddress) {
+ pub(crate) fn drop_device(&mut self, remote_address: RawAddress) {
if self.handles.contains_key(&remote_address) {
// Let BatteryProviderManager know that BAS no longer has a battery for this device.
self.battery_provider_manager.lock().unwrap().remove_battery_info(
@@ -354,6 +349,7 @@ impl BatteryService {
}
/// Status enum for relaying the state of BAS or a particular device.
+#[derive(Debug)]
pub enum BatteryServiceStatus {
/// Device does not report support for BAS.
BatteryServiceNotSupported,
diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs
index 3868212fc0..20442315c0 100644
--- a/system/gd/rust/linux/stack/src/bluetooth.rs
+++ b/system/gd/rust/linux/stack/src/bluetooth.rs
@@ -43,7 +43,6 @@ use tokio::sync::mpsc::Sender;
use tokio::task::JoinHandle;
use tokio::time;
-use crate::battery_service::BatteryServiceActions;
use crate::bluetooth_admin::BluetoothAdminPolicyHelper;
use crate::bluetooth_gatt::{
BluetoothGatt, GattActions, IBluetoothGatt, IScannerCallback, ScanResult,
@@ -375,6 +374,7 @@ struct BluetoothDeviceContext {
pub info: BluetoothDevice,
pub last_seen: Instant,
pub properties: HashMap<BtPropertyType, BluetoothProperty>,
+ pub is_hh_connected: bool,
/// If user wants to connect to all profiles, when new profiles are discovered we will also try
/// to connect them.
@@ -398,6 +398,7 @@ impl BluetoothDeviceContext {
info,
last_seen,
properties: HashMap::new(),
+ is_hh_connected: false,
connect_to_new_profiles: false,
};
device.update_properties(&properties);
@@ -1296,6 +1297,10 @@ impl Bluetooth {
|| self.pending_create_bond.is_some()
}
+ pub fn is_hh_connected(&self, device_address: &RawAddress) -> bool {
+ self.remote_devices.get(&device_address).map_or(false, |context| context.is_hh_connected)
+ }
+
/// Checks whether the list of device properties contains some UUID we should connect now
/// This function also connects those UUIDs.
fn check_new_property_and_potentially_connect_profiles(
@@ -1417,37 +1422,6 @@ impl Bluetooth {
});
}
- Profile::Bas => {
- has_supported_profile = true;
- let tx = self.tx.clone();
- let device_context = match self.remote_devices.get(&addr) {
- Some(context) => context,
- None => continue,
- };
-
- let acl_state = device_context.ble_acl_state.clone();
- let bond_state = device_context.bond_state.clone();
- let device_to_send = device.clone();
-
- let transport = match self.get_remote_type(device.clone()) {
- BtDeviceType::Bredr => BtTransport::Bredr,
- BtDeviceType::Ble => BtTransport::Le,
- _ => device_context.acl_reported_transport.clone(),
- };
- topstack::get_runtime().spawn(async move {
- let _ = tx
- .send(Message::BatteryService(
- BatteryServiceActions::Connect(
- device_to_send,
- acl_state,
- bond_state,
- transport,
- ),
- ))
- .await;
- });
- }
-
// We don't connect most profiles
_ => (),
}
@@ -1464,6 +1438,31 @@ impl Bluetooth {
self.resume_discovery();
}
}
+
+ fn fire_device_connection_or_bonded_state_changed(&self, addr: RawAddress) {
+ if let Some(device) = self.remote_devices.get(&addr) {
+ let tx = self.tx.clone();
+ let bredr_acl_state = device.bredr_acl_state.clone();
+ let ble_acl_state = device.ble_acl_state.clone();
+ let bond_state = device.bond_state.clone();
+ let transport = match self.get_remote_type(device.info.clone()) {
+ BtDeviceType::Bredr => BtTransport::Bredr,
+ BtDeviceType::Ble => BtTransport::Le,
+ _ => device.acl_reported_transport.clone(),
+ };
+ tokio::spawn(async move {
+ let _ = tx
+ .send(Message::OnDeviceConnectionOrBondStateChanged(
+ addr,
+ bredr_acl_state,
+ ble_acl_state,
+ bond_state,
+ transport,
+ ))
+ .await;
+ });
+ }
+ }
}
#[btif_callbacks_dispatcher(dispatch_base_callbacks, BaseCallbacks)]
@@ -1933,40 +1932,22 @@ impl BtifBluetoothCallbacks for Bluetooth {
Instant::now(),
vec![],
));
- let acl_reported_transport = device.acl_reported_transport.clone();
- let acl_state = device.ble_acl_state.clone();
let device_info = device.info.clone();
-
// Since this is a newly bonded device, we also need to trigger SDP on it.
- self.fetch_remote_uuids(device_info.clone());
+ self.fetch_remote_uuids(device_info);
if self.get_wake_allowed_device_bonded() {
self.create_uhid_for_suspend_wakesource();
}
// Update the connectable mode since bonded list is changed.
self.update_connectable_mode();
-
- let transport = match self.get_remote_type(device_info.clone()) {
- BtDeviceType::Bredr => BtTransport::Bredr,
- BtDeviceType::Ble => BtTransport::Le,
- _ => acl_reported_transport,
- };
-
- let tx = self.tx.clone();
- tokio::spawn(async move {
- let _ = tx
- .send(Message::OnDeviceConnectionStateChanged(
- device_info.clone(),
- acl_state,
- BtBondState::Bonded,
- transport,
- ))
- .await;
- });
}
BtBondState::Bonding => {}
}
}
+ // Modification to |self.remote_devices| has done, ok to fire the change event.
+ self.fire_device_connection_or_bonded_state_changed(addr);
+
// Resume discovery once the bonding process is complete. Discovery was paused before the
// bond request to avoid ACL connection from interfering with active inquiry.
if bond_state == BtBondState::NotBonded || bond_state == BtBondState::Bonded {
@@ -2073,7 +2054,6 @@ impl BtifBluetoothCallbacks for Bluetooth {
return;
}
- let txl = self.tx.clone();
let device = self.remote_devices.entry(addr).or_insert(BluetoothDeviceContext::new(
BtBondState::NotBonded,
BtAclState::Disconnected,
@@ -2090,7 +2070,6 @@ impl BtifBluetoothCallbacks for Bluetooth {
let info = device.info.clone();
device.acl_reported_transport = link_type;
- let bond_state = device.bond_state.clone();
metrics::acl_connection_state_changed(
addr,
@@ -2103,26 +2082,10 @@ impl BtifBluetoothCallbacks for Bluetooth {
match state {
BtAclState::Connected => {
- let acl_reported_transport = device.acl_reported_transport;
Bluetooth::send_metrics_remote_device_info(device);
self.connection_callbacks.for_all_callbacks(|callback| {
callback.on_device_connected(info.clone());
});
- let transport = match self.get_remote_type(info.clone()) {
- BtDeviceType::Bredr => BtTransport::Bredr,
- BtDeviceType::Ble => BtTransport::Le,
- _ => acl_reported_transport,
- };
- tokio::spawn(async move {
- let _ = txl
- .send(Message::OnDeviceConnectionStateChanged(
- info,
- BtAclState::Connected,
- bond_state,
- transport,
- ))
- .await;
- });
}
BtAclState::Disconnected => {
if !device.is_connected() {
@@ -2131,11 +2094,12 @@ impl BtifBluetoothCallbacks for Bluetooth {
});
device.connect_to_new_profiles = false;
}
- tokio::spawn(async move {
- let _ = txl.send(Message::OnDeviceDisconnected(info)).await;
- });
}
};
+
+ // Modification to |self.remote_devices| has done, ok to fire the change event.
+ self.fire_device_connection_or_bonded_state_changed(addr);
+
// If we are bonding, skip the update here as we will update it after bonding complete anyway.
// This is necessary for RTK controllers, which will break RNR after |Write Scan Enable|
// command. Although this is a bug of RTK controllers, but as we could avoid unwanted page
@@ -2848,18 +2812,6 @@ impl IBluetooth for Bluetooth {
});
}
- Profile::Bas => {
- let tx = self.tx.clone();
- let device_to_send = device.clone();
- topstack::get_runtime().spawn(async move {
- let _ = tx
- .send(Message::BatteryService(
- BatteryServiceActions::Disconnect(device_to_send),
- ))
- .await;
- });
- }
-
// We don't connect most profiles
_ => (),
}
@@ -3010,7 +2962,7 @@ impl BtifSdpCallbacks for Bluetooth {
impl BtifHHCallbacks for Bluetooth {
fn connection_state(
&mut self,
- mut address: RawAddress,
+ address: RawAddress,
address_type: BtAddrType,
transport: BtTransport,
state: BthhConnectionState,
@@ -3047,6 +2999,16 @@ impl BtifHHCallbacks for Bluetooth {
state as u32,
);
+ let tx = self.tx.clone();
+ self.remote_devices.entry(address).and_modify(|context| {
+ if context.is_hh_connected && state != BthhConnectionState::Connected {
+ tokio::spawn(async move {
+ let _ = tx.send(Message::ProfileDisconnected(address)).await;
+ });
+ }
+ context.is_hh_connected = state == BthhConnectionState::Connected;
+ });
+
if BtBondState::Bonded != self.get_bond_state_by_addr(&address)
&& (state != BthhConnectionState::Disconnecting
&& state != BthhConnectionState::Disconnected)
@@ -3057,6 +3019,7 @@ impl BtifHHCallbacks for Bluetooth {
);
// TODO(b/329837967): Determine correct reconnection
// behavior based on device instead of the default
+ let mut address = address;
self.hh.as_ref().unwrap().disconnect(
&mut address,
address_type,
diff --git a/system/gd/rust/linux/stack/src/bluetooth_gatt.rs b/system/gd/rust/linux/stack/src/bluetooth_gatt.rs
index 10368fbf49..d7361844d0 100644
--- a/system/gd/rust/linux/stack/src/bluetooth_gatt.rs
+++ b/system/gd/rust/linux/stack/src/bluetooth_gatt.rs
@@ -173,6 +173,14 @@ impl ContextMap {
.collect()
}
+ fn get_connected_applications_from_address(&self, address: &RawAddress) -> Vec<Uuid> {
+ self.get_client_ids_from_address(address)
+ .into_iter()
+ .filter_map(|id| self.get_by_client_id(id))
+ .map(|client| client.uuid)
+ .collect()
+ }
+
fn get_callback_from_callback_id(
&mut self,
callback_id: u32,
@@ -1872,6 +1880,10 @@ impl BluetoothGatt {
pub fn handle_adv_action(&mut self, action: AdvertiserActions) {
self.adv_manager.get_impl().handle_action(action);
}
+
+ pub(crate) fn get_connected_applications(&self, device_address: &RawAddress) -> Vec<Uuid> {
+ self.context_map.get_connected_applications_from_address(device_address)
+ }
}
#[derive(Debug, FromPrimitive, ToPrimitive)]
@@ -2865,6 +2877,11 @@ impl BtifGattClientCallbacks for BluetoothGatt {
}
}
}
+
+ let tx = self.tx.clone();
+ tokio::spawn(async move {
+ let _ = tx.send(Message::ProfileDisconnected(addr)).await;
+ });
}
fn search_complete_cb(&mut self, conn_id: i32, _status: GattStatus) {
diff --git a/system/gd/rust/linux/stack/src/bluetooth_media.rs b/system/gd/rust/linux/stack/src/bluetooth_media.rs
index b31cc1c7e2..4e6f6d2811 100644
--- a/system/gd/rust/linux/stack/src/bluetooth_media.rs
+++ b/system/gd/rust/linux/stack/src/bluetooth_media.rs
@@ -609,6 +609,10 @@ impl BluetoothMedia {
false
}
+ pub(crate) fn get_connected_profiles(&self, device_address: &RawAddress) -> HashSet<Profile> {
+ self.connected_profiles.get(device_address).cloned().unwrap_or_default()
+ }
+
fn add_connected_profile(&mut self, addr: RawAddress, profile: Profile) {
if self.is_profile_connected(&addr, &profile) {
warn!("[{}]: profile is already connected", DisplayAddress(&addr));
@@ -2302,6 +2306,10 @@ impl BluetoothMedia {
self.connected_profiles.remove(&addr);
states.remove(&addr);
guard.remove(&addr);
+ let tx = self.tx.clone();
+ tokio::spawn(async move {
+ let _ = tx.send(Message::ProfileDisconnected(addr)).await;
+ });
return;
}
diff --git a/system/gd/rust/linux/stack/src/lib.rs b/system/gd/rust/linux/stack/src/lib.rs
index b13e66b523..e540e68d3e 100644
--- a/system/gd/rust/linux/stack/src/lib.rs
+++ b/system/gd/rust/linux/stack/src/lib.rs
@@ -20,7 +20,7 @@ pub mod suspend;
pub mod uuid;
use bluetooth_qa::{BluetoothQA, IBluetoothQA};
-use log::debug;
+use log::{debug, info};
use num_derive::{FromPrimitive, ToPrimitive};
use std::sync::{Arc, Mutex};
use tokio::sync::mpsc::channel;
@@ -29,7 +29,9 @@ use tokio::time::{sleep, Duration};
use crate::battery_manager::{BatteryManager, BatterySet};
use crate::battery_provider_manager::BatteryProviderManager;
-use crate::battery_service::{BatteryService, BatteryServiceActions};
+use crate::battery_service::{
+ BatteryService, BatteryServiceActions, BATTERY_SERVICE_GATT_CLIENT_APP_ID,
+};
use crate::bluetooth::{
dispatch_base_callbacks, dispatch_hid_host_callbacks, dispatch_sdp_callbacks, AdapterActions,
Bluetooth, BluetoothDevice, IBluetooth,
@@ -45,7 +47,7 @@ use crate::dis::{DeviceInformation, ServiceCallbacks};
use crate::socket_manager::{BluetoothSocketManager, SocketActions};
use crate::suspend::Suspend;
use bt_topshim::{
- btif::{BaseCallbacks, BtAclState, BtBondState, BtTransport, RawAddress},
+ btif::{BaseCallbacks, BtAclState, BtBondState, BtTransport, DisplayAddress, RawAddress, Uuid},
profiles::{
a2dp::A2dpCallbacks,
avrcp::AvrcpCallbacks,
@@ -109,8 +111,14 @@ pub enum Message {
// Follows IBluetooth's on_device_(dis)connected and bond_state callbacks
// but doesn't require depending on Bluetooth.
- OnDeviceConnectionStateChanged(BluetoothDevice, BtAclState, BtBondState, BtTransport),
- OnDeviceDisconnected(BluetoothDevice),
+ // Params: Address, BR/EDR ACL state, BLE ACL state, bond state, transport
+ OnDeviceConnectionOrBondStateChanged(
+ RawAddress,
+ BtAclState,
+ BtAclState,
+ BtBondState,
+ BtTransport,
+ ),
// Suspend related
SuspendCallbackRegistered(u32),
@@ -167,6 +175,11 @@ pub enum Message {
// UHid callbacks
UHidHfpOutputCallback(RawAddress, u8, u8),
UHidTelephonyUseCallback(RawAddress, bool),
+
+ // This message is sent when either HID, media, or GATT client, is disconnected.
+ // Note that meida sends this when the profiles are disconnected as a whole, that is, it will
+ // not be called when AVRCP is disconnected but not A2DP, as an example.
+ ProfileDisconnected(RawAddress),
}
/// Returns a callable object that dispatches a BTIF callback to Message
@@ -432,27 +445,19 @@ impl Stack {
bluetooth.lock().unwrap().handle_actions(action);
}
- // Any service needing an updated list of devices can have an
- // update method triggered from here rather than needing a
- // reference to Bluetooth.
- Message::OnDeviceConnectionStateChanged(
- device,
- acl_state,
+ // Any service needing an updated list of devices can have an update method
+ // triggered from here rather than needing a reference to Bluetooth.
+ Message::OnDeviceConnectionOrBondStateChanged(
+ addr,
+ _bredr_acl_state,
+ ble_acl_state,
bond_state,
- transport,
+ _transport,
) => {
- battery_service.lock().unwrap().handle_action(BatteryServiceActions::Connect(
- device, acl_state, bond_state, transport,
- ));
- }
-
- // For battery service, use this to clean up internal handles. GATT connection is
- // already dropped if ACL disconnect has occurred.
- Message::OnDeviceDisconnected(device) => {
- battery_service
- .lock()
- .unwrap()
- .handle_action(BatteryServiceActions::Disconnect(device));
+ if ble_acl_state == BtAclState::Connected && bond_state == BtBondState::Bonded {
+ info!("BAS: Connecting to {}", DisplayAddress(&addr));
+ battery_service.lock().unwrap().init_device(addr);
+ }
}
Message::SuspendCallbackRegistered(id) => {
@@ -599,6 +604,26 @@ impl Stack {
.unwrap()
.dispatch_uhid_telephony_use_callback(addr, state);
}
+
+ Message::ProfileDisconnected(addr) => {
+ let bas_app_uuid =
+ Uuid::from_string(String::from(BATTERY_SERVICE_GATT_CLIENT_APP_ID))
+ .expect("BAS Uuid failed to be parsed");
+ // Ideally we would also check that there are no open sockets for this device
+ // but Floss does not manage socket state so there is no reasonable way for us
+ // to know whether a socket is open or not.
+ if bluetooth_gatt.lock().unwrap().get_connected_applications(&addr)
+ == vec![bas_app_uuid]
+ && !bluetooth.lock().unwrap().is_hh_connected(&addr)
+ && bluetooth_media.lock().unwrap().get_connected_profiles(&addr).is_empty()
+ {
+ info!(
+ "BAS: Disconnecting from {} since it's the last active profile",
+ DisplayAddress(&addr)
+ );
+ battery_service.lock().unwrap().drop_device(addr);
+ }
+ }
}
}
}
diff --git a/system/gd/rust/topshim/csis/csis_shim.cc b/system/gd/rust/topshim/csis/csis_shim.cc
index 371d4976f5..c08deb019d 100644
--- a/system/gd/rust/topshim/csis/csis_shim.cc
+++ b/system/gd/rust/topshim/csis/csis_shim.cc
@@ -21,7 +21,6 @@
#include <string>
-#include "os/log.h"
#include "src/profiles/csis.rs.h"
#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"
@@ -101,19 +100,18 @@ public:
DBusCsisClientCallbacks() {}
void OnConnectionState(const RawAddress& addr, csis::ConnectionState state) override {
- log::info("addr={}, state={}", ADDRESS_TO_LOGGABLE_CSTR(addr), static_cast<uint8_t>(state));
+ log::info("addr={}, state={}", addr, static_cast<uint8_t>(state));
topshim::rust::internal::connection_state_cb(addr, state);
}
void OnDeviceAvailable(const RawAddress& addr, int group_id, int group_size, int rank,
const bluetooth::Uuid& uuid) override {
- log::info("addr={}, group_id={}, group_size={}, rank={}", ADDRESS_TO_LOGGABLE_CSTR(addr),
- group_id, group_size, rank);
+ log::info("addr={}, group_id={}, group_size={}, rank={}", addr, group_id, group_size, rank);
topshim::rust::internal::device_available_cb(addr, group_id, group_size, rank, uuid);
}
void OnSetMemberAvailable(const RawAddress& addr, int group_id) {
- log::info("addr={}, group_id={}", ADDRESS_TO_LOGGABLE_CSTR(addr), group_id);
+ log::info("addr={}, group_id={}", addr, group_id);
topshim::rust::internal::set_member_available_cb(addr, group_id);
}
diff --git a/system/gd/rust/topshim/hfp/hfp_shim.cc b/system/gd/rust/topshim/hfp/hfp_shim.cc
index 12c338e535..549b54a479 100644
--- a/system/gd/rust/topshim/hfp/hfp_shim.cc
+++ b/system/gd/rust/topshim/hfp/hfp_shim.cc
@@ -22,7 +22,6 @@
#include "common/strings.h"
#include "device/include/interop.h"
#include "include/hardware/bt_hf.h"
-#include "os/log.h"
#include "src/profiles/hfp.rs.h"
#include "types/raw_address.h"
diff --git a/system/gd/rust/topshim/le_audio/le_audio_shim.cc b/system/gd/rust/topshim/le_audio/le_audio_shim.cc
index bb70fc37d0..77d7a5c60d 100644
--- a/system/gd/rust/topshim/le_audio/le_audio_shim.cc
+++ b/system/gd/rust/topshim/le_audio/le_audio_shim.cc
@@ -22,7 +22,6 @@
#include <vector>
#include "bta/le_audio/le_audio_types.h"
-#include "os/log.h"
#include "src/profiles/le_audio.rs.h"
#include "types/raw_address.h"
@@ -253,7 +252,7 @@ public:
}
void OnConnectionState(le_audio::ConnectionState state, const RawAddress& address) override {
- log::info("state={}, address={}", static_cast<int>(state), ADDRESS_TO_LOGGABLE_CSTR(address));
+ log::info("state={}, address={}", static_cast<int>(state), address);
topshim::rust::internal::connection_state_cb(state, address);
}
@@ -264,8 +263,8 @@ public:
void OnGroupNodeStatus(const RawAddress& bd_addr, int group_id,
le_audio::GroupNodeStatus node_status) {
- log::info("bd_addr={}, group_id={}, node_status={}", ADDRESS_TO_LOGGABLE_CSTR(bd_addr),
- group_id, static_cast<int>(node_status));
+ log::info("bd_addr={}, group_id={}, node_status={}", bd_addr, group_id,
+ static_cast<int>(node_status));
topshim::rust::internal::group_node_status_cb(bd_addr, group_id, node_status);
}
@@ -280,8 +279,7 @@ public:
}
void OnSinkAudioLocationAvailable(const RawAddress& address, uint32_t snk_audio_locations) {
- log::info("address={}, snk_audio_locations={}", ADDRESS_TO_LOGGABLE_CSTR(address),
- snk_audio_locations);
+ log::info("address={}, snk_audio_locations={}", address, snk_audio_locations);
topshim::rust::internal::sink_audio_location_available_cb(address, snk_audio_locations);
}
@@ -323,7 +321,7 @@ public:
void OnHealthBasedRecommendationAction(const RawAddress& address,
le_audio::LeAudioHealthBasedAction action) {
- log::info("address={}, action={}", ADDRESS_TO_LOGGABLE_CSTR(address), static_cast<int>(action));
+ log::info("address={}, action={}", address, static_cast<int>(action));
}
void OnHealthBasedGroupRecommendationAction(int group_id,
diff --git a/system/gd/rust/topshim/vc/vc_shim.cc b/system/gd/rust/topshim/vc/vc_shim.cc
index 55d8369db6..f7f68d5af2 100644
--- a/system/gd/rust/topshim/vc/vc_shim.cc
+++ b/system/gd/rust/topshim/vc/vc_shim.cc
@@ -21,7 +21,6 @@
#include <string>
-#include "os/log.h"
#include "src/profiles/vc.rs.h"
#include "types/raw_address.h"
@@ -94,14 +93,14 @@ public:
DBusVolumeControlCallbacks() {}
void OnConnectionState(vc::ConnectionState state, const RawAddress& address) override {
- log::info("state={}, address={}", static_cast<int>(state), ADDRESS_TO_LOGGABLE_CSTR(address));
+ log::info("state={}, address={}", static_cast<int>(state), address);
topshim::rust::internal::connection_state_cb(state, address);
}
void OnVolumeStateChanged(const RawAddress& address, uint8_t volume, bool mute, uint8_t flags,
bool is_autonomous) override {
- log::info("address={}, volume={}, mute={}, flags={}, is_autonomous={}",
- ADDRESS_TO_LOGGABLE_CSTR(address), volume, mute, flags, is_autonomous);
+ log::info("address={}, volume={}, mute={}, flags={}, is_autonomous={}", address, volume, mute,
+ flags, is_autonomous);
topshim::rust::internal::volume_state_cb(address, volume, mute, is_autonomous);
}
@@ -120,22 +119,19 @@ public:
void OnExtAudioOutVolumeOffsetChanged(const RawAddress& address, uint8_t ext_output_id,
int16_t offset) override {
- log::info("address={}, ext_output_id={}, offset={}", ADDRESS_TO_LOGGABLE_CSTR(address),
- ext_output_id, offset);
+ log::info("address={}, ext_output_id={}, offset={}", address, ext_output_id, offset);
topshim::rust::internal::ext_audio_out_volume_offset_cb(address, ext_output_id, offset);
}
void OnExtAudioOutLocationChanged(const RawAddress& address, uint8_t ext_output_id,
uint32_t location) override {
- log::info("address={}, ext_output_id, location={}", ADDRESS_TO_LOGGABLE_CSTR(address),
- ext_output_id, location);
+ log::info("address={}, ext_output_id, location={}", address, ext_output_id, location);
topshim::rust::internal::ext_audio_out_location_cb(address, ext_output_id, location);
}
void OnExtAudioOutDescriptionChanged(const RawAddress& address, uint8_t ext_output_id,
std::string descr) override {
- log::info("address={}, ext_output_id={}, descr={}", ADDRESS_TO_LOGGABLE_CSTR(address),
- ext_output_id, descr.c_str());
+ log::info("address={}, ext_output_id={}, descr={}", address, ext_output_id, descr.c_str());
topshim::rust::internal::ext_audio_out_description_cb(address, ext_output_id, descr);
}
diff --git a/system/gd/shim/dumpsys.cc b/system/gd/shim/dumpsys.cc
index 24a0083175..30d9f70c0b 100644
--- a/system/gd/shim/dumpsys.cc
+++ b/system/gd/shim/dumpsys.cc
@@ -30,7 +30,6 @@
#include "main/shim/stack.h"
#include "module.h"
#include "module_dumper.h"
-#include "os/log.h"
#include "os/system_properties.h"
#include "shim/dumpsys.h"
diff --git a/system/gd/stack_manager.cc b/system/gd/stack_manager.cc
index d62507400c..856d10a3c4 100644
--- a/system/gd/stack_manager.cc
+++ b/system/gd/stack_manager.cc
@@ -25,7 +25,6 @@
#include "common/bind.h"
#include "module.h"
#include "os/handler.h"
-#include "os/log.h"
#include "os/system_properties.h"
#include "os/thread.h"
#include "os/wakelock_manager.h"
diff --git a/system/gd/storage/device.cc b/system/gd/storage/device.cc
index 50d973bdc5..7210a110fe 100644
--- a/system/gd/storage/device.cc
+++ b/system/gd/storage/device.cc
@@ -21,7 +21,6 @@
#include <algorithm>
#include <limits>
-#include "os/log.h"
#include "storage/classic_device.h"
#include "storage/config_cache_helper.h"
#include "storage/le_device.h"
diff --git a/system/gd/storage/legacy_config_file.cc b/system/gd/storage/legacy_config_file.cc
index a64be377ea..0bee52af03 100644
--- a/system/gd/storage/legacy_config_file.cc
+++ b/system/gd/storage/legacy_config_file.cc
@@ -24,7 +24,6 @@
#include "common/strings.h"
#include "os/files.h"
-#include "os/log.h"
#include "storage/device.h"
namespace bluetooth {
diff --git a/system/gd/storage/mutation.cc b/system/gd/storage/mutation.cc
index c0dacdcc80..559a0415d9 100644
--- a/system/gd/storage/mutation.cc
+++ b/system/gd/storage/mutation.cc
@@ -16,8 +16,6 @@
#include "storage/mutation.h"
-#include "os/log.h"
-
namespace bluetooth {
namespace storage {
diff --git a/system/gd/storage/mutation.h b/system/gd/storage/mutation.h
index ddaf5804f2..493faddace 100644
--- a/system/gd/storage/mutation.h
+++ b/system/gd/storage/mutation.h
@@ -17,7 +17,6 @@
#include <queue>
-#include "os/log.h"
#include "storage/config_cache.h"
#include "storage/mutation_entry.h"
diff --git a/system/gd/storage/mutation_entry.cc b/system/gd/storage/mutation_entry.cc
index 6d078d60a8..f1c930e576 100644
--- a/system/gd/storage/mutation_entry.cc
+++ b/system/gd/storage/mutation_entry.cc
@@ -16,8 +16,6 @@
#include "storage/mutation_entry.h"
-#include "os/log.h"
-
namespace bluetooth {
namespace storage {
diff --git a/system/gd/sysprops/sysprops_module.cc b/system/gd/sysprops/sysprops_module.cc
index dfb5bfbc5a..0cdcaa2efa 100644
--- a/system/gd/sysprops/sysprops_module.cc
+++ b/system/gd/sysprops/sysprops_module.cc
@@ -19,7 +19,6 @@
#include <filesystem>
#include "os/handler.h"
-#include "os/log.h"
#include "os/parameter_provider.h"
#include "os/system_properties.h"
#include "storage/legacy_config_file.h"
diff --git a/system/hci/src/packet_fragmenter.cc b/system/hci/src/packet_fragmenter.cc
index 9ecb6bd7b5..c95c25dfe6 100644
--- a/system/hci/src/packet_fragmenter.cc
+++ b/system/hci/src/packet_fragmenter.cc
@@ -28,7 +28,6 @@
#include "hci/include/buffer_allocator.h"
#include "hci/include/hci_layer.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_types.h"
diff --git a/system/include/hardware/bt_vc.h b/system/include/hardware/bt_vc.h
index 420e91778b..7d24a07543 100644
--- a/system/include/hardware/bt_vc.h
+++ b/system/include/hardware/bt_vc.h
@@ -26,6 +26,7 @@
namespace bluetooth {
namespace vc {
+// Must be kept in sync with BluetoothProfile.java
enum class ConnectionState { DISCONNECTED = 0, CONNECTING, CONNECTED, DISCONNECTING };
/* Audio input types */
diff --git a/system/internal_include/bt_target.h b/system/internal_include/bt_target.h
index 7aeb11a24f..edb4eb712e 100644
--- a/system/internal_include/bt_target.h
+++ b/system/internal_include/bt_target.h
@@ -311,7 +311,10 @@
#endif
/* Used for conformance testing ONLY: When TRUE lets scriptwrapper overwrite
- * info response */
+ * info response.
+ * For testcases L2CAP/FOC/BV-{04,05}-C set property bluetooth.pts.l2cap.foc.bv.test to 4 and
+ * 5 respectively
+ */
#ifndef L2CAP_CONFORMANCE_TESTING
#define L2CAP_CONFORMANCE_TESTING FALSE
#endif
diff --git a/system/main/shim/config.cc b/system/main/shim/config.cc
index efa9e14221..a2568e455c 100644
--- a/system/main/shim/config.cc
+++ b/system/main/shim/config.cc
@@ -23,7 +23,6 @@
#include <cstring>
#include "main/shim/entry.h"
-#include "os/log.h"
#include "storage/storage_module.h"
using ::bluetooth::shim::GetStorage;
diff --git a/system/main/stack_config.cc b/system/main/stack_config.cc
index ae5ebc4da5..9b04e7f16c 100644
--- a/system/main/stack_config.cc
+++ b/system/main/stack_config.cc
@@ -22,7 +22,6 @@
#include <bluetooth/log.h>
-#include "os/log.h"
#include "osi/include/future.h"
using namespace bluetooth;
diff --git a/system/osi/src/alarm.cc b/system/osi/src/alarm.cc
index 0d515c486d..a280442bb0 100644
--- a/system/osi/src/alarm.cc
+++ b/system/osi/src/alarm.cc
@@ -32,7 +32,6 @@
#include <mutex>
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/fixed_queue.h"
#include "osi/include/list.h"
diff --git a/system/osi/src/future.cc b/system/osi/src/future.cc
index 63dc254123..ce8c7f0b4b 100644
--- a/system/osi/src/future.cc
+++ b/system/osi/src/future.cc
@@ -22,7 +22,6 @@
#include <bluetooth/log.h>
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/osi.h"
#include "osi/semaphore.h"
diff --git a/system/osi/src/internal/semaphore.cc b/system/osi/src/internal/semaphore.cc
index 23aa60c131..8f2706862f 100644
--- a/system/osi/src/internal/semaphore.cc
+++ b/system/osi/src/internal/semaphore.cc
@@ -27,7 +27,6 @@
#include <sys/eventfd.h>
#include <unistd.h>
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/osi.h"
diff --git a/system/osi/src/reactor.cc b/system/osi/src/reactor.cc
index 045bc24f3c..82522172c5 100644
--- a/system/osi/src/reactor.cc
+++ b/system/osi/src/reactor.cc
@@ -30,7 +30,6 @@
#include <mutex>
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/list.h"
diff --git a/system/osi/src/socket.cc b/system/osi/src/socket.cc
index c1694e68c3..0c7c96b71c 100644
--- a/system/osi/src/socket.cc
+++ b/system/osi/src/socket.cc
@@ -28,7 +28,6 @@
#include <sys/socket.h>
#include <unistd.h>
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/osi.h"
#include "osi/include/reactor.h"
diff --git a/system/osi/src/stack_power_telemetry.cc b/system/osi/src/stack_power_telemetry.cc
index f8ca11e32c..262bb2afb2 100644
--- a/system/osi/src/stack_power_telemetry.cc
+++ b/system/osi/src/stack_power_telemetry.cc
@@ -28,7 +28,7 @@
#include <map>
#include <mutex>
-#include "os/log.h"
+#include "os/logging/log_adapter.h"
#include "osi/include/properties.h"
#include "stack/include/acl_api_types.h"
#include "stack/include/bt_psm_types.h"
diff --git a/system/osi/src/thread.cc b/system/osi/src/thread.cc
index b43a576458..0fa15fc6d3 100644
--- a/system/osi/src/thread.cc
+++ b/system/osi/src/thread.cc
@@ -32,7 +32,6 @@
#include <atomic>
#include <cerrno>
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/compat.h"
#include "osi/include/fixed_queue.h"
diff --git a/system/osi/src/wakelock.cc b/system/osi/src/wakelock.cc
index 9865ecb16a..5cae5ed580 100644
--- a/system/osi/src/wakelock.cc
+++ b/system/osi/src/wakelock.cc
@@ -34,7 +34,6 @@
#include <string>
#include "common/metrics.h"
-#include "os/log.h"
#include "osi/include/osi.h"
using bluetooth::common::BluetoothMetricsLogger;
diff --git a/system/packet/tests/fuzzers/Android.bp b/system/packet/tests/fuzzers/Android.bp
index e15bbdc993..00ea544c82 100644
--- a/system/packet/tests/fuzzers/Android.bp
+++ b/system/packet/tests/fuzzers/Android.bp
@@ -7,11 +7,10 @@ package {
default_applicable_licenses: ["system_bt_license"],
}
-cc_fuzz {
- name: "avrcp_browse_packet_fuzzer",
+cc_defaults {
+ name: "packet_avrcp_fuzz_defaults",
defaults: ["fluoride_defaults"],
host_supported: true,
-
include_dirs: [
"packages/modules/Bluetooth/system/",
"packages/modules/Bluetooth/system/gd",
@@ -21,13 +20,6 @@ cc_fuzz {
"packages/modules/Bluetooth/system/packet/tests",
"packages/modules/Bluetooth/system/packet/tests/avrcp",
],
- srcs: [
- "avrcp_browse_packet_fuzzer.cc",
-
- ],
-
- corpus: ["corpus/avrcp_browse_packets_corpus/*"],
-
static_libs: [
"lib-bt-packets",
"lib-bt-packets-avrcp",
@@ -47,961 +39,176 @@ cc_fuzz {
}
cc_fuzz {
- name: "change_path_req_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
- //system/libbase/include/android-base"
- srcs: [
- "change_path_req_fuzzer.cc",
-
- ],
+ name: "avrcp_browse_packet_fuzzer",
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["avrcp_browse_packet_fuzzer.cc"],
+ corpus: ["corpus/avrcp_browse_packets_corpus/*"],
+}
+cc_fuzz {
+ name: "change_path_req_fuzzer",
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["change_path_req_fuzzer.cc"],
corpus: ["corpus/change_path_req_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "get_capabilities_req_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "get_capabilities_req_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["get_capabilities_req_fuzzer.cc"],
corpus: ["corpus/get_capabilities_req_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "get_capabilities_res_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "get_capabilities_res_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["get_capabilities_res_fuzzer.cc"],
corpus: ["corpus/get_capabilities_res_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "get_item_attributes_req_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "get_item_attributes_req_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["get_item_attributes_req_fuzzer.cc"],
corpus: ["corpus/get_item_attributes_req_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "get_play_status_req_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "get_play_status_req_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["get_play_status_req_fuzzer.cc"],
corpus: ["get_play_status_req_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "get_total_number_of_items_req_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "get_total_number_of_items_req_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["get_total_number_of_items_req_fuzzer.cc"],
corpus: ["corpus/get_total_number_of_items_req_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "pass_through_packet_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "pass_through_packet_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["pass_through_packet_fuzzer.cc"],
corpus: ["corpus/pass_through_packet_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "play_item_packet_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "play_item_packet_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["play_item_packet_fuzzer.cc"],
corpus: ["corpus/play_item_packet_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "register_notification_packet_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "register_notification_packet_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["register_notification_packet_fuzzer.cc"],
corpus: ["corpus/register_notification_packet_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "set_absolute_volume_packet_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "set_absolute_volume_packet_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["set_absolute_volume_packet_fuzzer.cc"],
corpus: ["corpus/set_absolute_volume_packet_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "set_addressed_player_packet_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "set_addressed_player_packet_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["set_addressed_player_packet_fuzzer.cc"],
corpus: ["corpus/set_addressed_player_packet_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "set_browsed_player_req_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "set_browsed_player_req_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["set_browsed_player_req_fuzzer.cc"],
corpus: ["corpus/set_browsed_player_req_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "vendor_packet_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "vendor_packet_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["vendor_packet_fuzzer.cc"],
corpus: ["corpus/vendor_packet_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "avrcp_packet_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "avrcp_packet_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["avrcp_packet_fuzzer.cc"],
corpus: ["corpus/avrcp_packet_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "reject_packet_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "reject_packet_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["reject_packet_fuzzer.cc"],
corpus: ["corpus/reject_packet_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "get_element_attributes_req_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "get_element_attributes_req_packet_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["get_element_attributes_req_packet_fuzzer.cc"],
corpus: ["corpus/get_element_attributes_req_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "change_path_res_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "change_path_res_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["change_path_res_fuzzer.cc"],
corpus: ["corpus/change_path_res_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "get_element_attributes_res_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "get_element_attributes_res_packet_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["get_element_attributes_res_packet_fuzzer.cc"],
corpus: ["corpus/get_element_attributes_res_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "get_folder_items_res_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "get_folder_items_res_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["get_folder_items_res_fuzzer.cc"],
corpus: ["corpus/get_folder_items_res_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "get_folder_items_req_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "get_folder_items_req_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["get_folder_items_req_fuzzer.cc"],
corpus: ["corpus/get_folder_items_req_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "get_item_attributes_res_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "get_item_attributes_res_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["get_item_attributes_res_fuzzer.cc"],
corpus: ["corpus/get_item_attributes_res_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "get_play_status_res_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "get_play_status_res_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["get_play_status_res_fuzzer.cc"],
corpus: ["corpus/get_play_status_res_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "get_total_number_of_items_res_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "get_total_number_of_items_res_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["get_total_number_of_items_res_fuzzer.cc"],
corpus: ["corpus/get_total_number_of_items_res_corpus/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
cc_fuzz {
name: "set_browsed_player_res_fuzzer",
- defaults: ["fluoride_defaults"],
- host_supported: true,
-
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- "packages/modules/Bluetooth/system/include",
- "packages/modules/Bluetooth/system/packet/base",
- "packages/modules/Bluetooth/system/packet/include",
- "packages/modules/Bluetooth/system/packet/tests",
- "packages/modules/Bluetooth/system/packet/tests/avrcp",
- ],
-
- srcs: [
- "set_browsed_player_res_fuzzer.cc",
-
- ],
-
+ defaults: ["packet_avrcp_fuzz_defaults"],
+ srcs: ["set_browsed_player_res_fuzzer.cc"],
corpus: ["corpus/set_browsed_player_res_fuzzer/*"],
-
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- ],
- cflags: [
- "-Wno-missing-prototypes",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
}
diff --git a/system/pdl/hci/hci_packets.pdl b/system/pdl/hci/hci_packets.pdl
index 76673e2aae..df7c47db2a 100644
--- a/system/pdl/hci/hci_packets.pdl
+++ b/system/pdl/hci/hci_packets.pdl
@@ -4943,7 +4943,7 @@ struct CsOptionalCsSyncPhysSupported {
}
struct CsOptionalSubfeaturesSupported {
- _reserved_ : 1,
+ companion_signal : 1,
frequency_actuation_error : 1,
channel_selection_algorithm : 1,
phase_based_ranging : 1,
@@ -5129,7 +5129,7 @@ enum CsRole : 8 {
}
enum CsConfigRttType : 8 {
- RTT_AA_ONLY = 0x00,
+ RTT_AA_COARSE = 0x00,
RTT_WITH_32_BIT_SOUNDING_SEQUENCE = 0x01,
RTT_WITH_96_BIT_SOUNDING_SEQUENCE = 0x02,
RTT_WITH_32_BIT_RANDOM_SEQUENCE = 0x03,
@@ -6879,7 +6879,6 @@ packet LeCsProcedureEnableComplete : LeMetaEvent (subevent_code = LE_CS_PROCEDUR
event_interval : 16,
procedure_interval : 16,
procedure_count : 16,
- max_procedure_len : 16,
}
struct LeCsMode0InitatorData {
diff --git a/system/profile/avrcp/avrcp_internal.h b/system/profile/avrcp/avrcp_internal.h
index 665382ce61..a863cb7cf5 100644
--- a/system/profile/avrcp/avrcp_internal.h
+++ b/system/profile/avrcp/avrcp_internal.h
@@ -16,11 +16,9 @@
#pragma once
-#include "avrcp_config.h"
#include "stack/include/a2dp_api.h"
#include "stack/include/avrc_api.h"
#include "stack/include/bt_hdr.h"
-#include "stack/include/sdp_api.h"
#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"
@@ -48,7 +46,7 @@ public:
virtual uint16_t Open(uint8_t* p_handle, tAVRC_CONN_CB* p_ccb, const RawAddress& bd_addr) = 0;
- virtual uint16_t OpenBrowse(uint8_t handle, uint8_t conn_role) = 0;
+ virtual uint16_t OpenBrowse(uint8_t handle, tAVCT_ROLE conn_role) = 0;
virtual uint16_t GetPeerMtu(uint8_t handle) = 0;
diff --git a/system/profile/avrcp/connection_handler.cc b/system/profile/avrcp/connection_handler.cc
index 6faf5cf0e7..9608294161 100644
--- a/system/profile/avrcp/connection_handler.cc
+++ b/system/profile/avrcp/connection_handler.cc
@@ -233,14 +233,14 @@ bool ConnectionHandler::AvrcpConnect(bool initiator, const RawAddress& bdaddr) {
}
open_cb.msg_cback = base::Bind(&ConnectionHandler::MessageCb, weak_ptr_factory_.GetWeakPtr());
open_cb.company_id = AVRC_CO_GOOGLE;
- open_cb.conn = initiator ? AVRC_CONN_INT : AVRC_CONN_ACP; // 0 if initiator, 1 if acceptor
+ open_cb.conn = initiator ? AVCT_ROLE_INITIATOR : AVCT_ROLE_ACCEPTOR;
// TODO (apanicke): We shouldn't need RCCT to do absolute volume. The current
// AVRC_API requires it though.
open_cb.control = BTA_AV_FEAT_RCTG | BTA_AV_FEAT_RCCT | BTA_AV_FEAT_METADATA | AVRC_CT_PASSIVE;
uint8_t handle = 0;
uint16_t status = avrc_->Open(&handle, &open_cb, bdaddr);
- log::info("handle=0x{:x} status= 0x{:x}", handle, status);
+ log::info("handle=0x{:x} status=0x{:x}", handle, status);
return status == AVRC_SUCCESS;
}
@@ -266,7 +266,7 @@ void ConnectionHandler::InitiatorControlCb(uint8_t handle, uint8_t event, uint16
bool supports_browsing = feature_iter->second & BTA_AV_FEAT_BROWSE;
if (supports_browsing) {
- avrc_->OpenBrowse(handle, AVCT_INT);
+ avrc_->OpenBrowse(handle, AVCT_ROLE_INITIATOR);
}
// TODO (apanicke): Implement a system to cache SDP entries. For most
@@ -395,7 +395,7 @@ void ConnectionHandler::AcceptorControlCb(uint8_t handle, uint8_t event, uint16_
};
if (SdpLookup(*peer_addr, base::Bind(sdp_lambda, this, handle), false)) {
- avrc_->OpenBrowse(handle, AVCT_ACP);
+ avrc_->OpenBrowse(handle, AVCT_ROLE_ACCEPTOR);
} else {
// SDP search failed, this could be due to a collision between outgoing
// and incoming connection. In any case, we need to reject the current
diff --git a/system/profile/avrcp/tests/avrcp_connection_handler_test.cc b/system/profile/avrcp/tests/avrcp_connection_handler_test.cc
index 73334576f1..080bda09f3 100644
--- a/system/profile/avrcp/tests/avrcp_connection_handler_test.cc
+++ b/system/profile/avrcp/tests/avrcp_connection_handler_test.cc
@@ -206,7 +206,7 @@ TEST_F(AvrcpConnectionHandlerTest, remoteDeviceConnectionTest) {
// Set an Expectation that OpenBrowse will be called in acceptor mode when the
// device connects.
- EXPECT_CALL(mock_avrcp_, OpenBrowse(1, AVCT_ACP)).Times(1);
+ EXPECT_CALL(mock_avrcp_, OpenBrowse(1, AVCT_ROLE_ACCEPTOR)).Times(1);
if (com::android::bluetooth::flags::avrcp_connect_a2dp_with_delay()) {
// Set an expectation that SDP for audio will be performed
@@ -374,7 +374,7 @@ TEST_F(AvrcpConnectionHandlerTest, multipleRemoteDeviceConnectionTest) {
// Set an Expectation that OpenBrowse will be called in acceptor mode when the
// device connects on handle 1
- EXPECT_CALL(mock_avrcp_, OpenBrowse(1, AVCT_ACP)).Times(1);
+ EXPECT_CALL(mock_avrcp_, OpenBrowse(1, AVCT_ROLE_ACCEPTOR)).Times(1);
// Call the callback with a message saying that a remote device has connected
conn_cb.ctrl_cback.Run(1, AVRC_OPEN_IND_EVT, 0, &RawAddress::kAny);
@@ -391,7 +391,7 @@ TEST_F(AvrcpConnectionHandlerTest, multipleRemoteDeviceConnectionTest) {
// Set an Expectation that OpenBrowse will be called in acceptor mode when the
// device connects on handle 2
- EXPECT_CALL(mock_avrcp_, OpenBrowse(2, AVCT_ACP)).Times(1);
+ EXPECT_CALL(mock_avrcp_, OpenBrowse(2, AVCT_ROLE_ACCEPTOR)).Times(1);
// Call the callback with a message saying that a remote device has connected
// with a different address
@@ -504,7 +504,7 @@ TEST_F(AvrcpConnectionHandlerTest, connectToBrowsableRemoteDeviceTest) {
// Set an Expectation that OpenBrowse will be called since browsing is listed
// as supported in SDP
- EXPECT_CALL(mock_avrcp_, OpenBrowse(1, AVCT_INT)).Times(1);
+ EXPECT_CALL(mock_avrcp_, OpenBrowse(1, AVCT_ROLE_INITIATOR)).Times(1);
// Call the callback with a message saying that a remote device has connected
// with a different address
diff --git a/system/profile/avrcp/tests/avrcp_test_helper.h b/system/profile/avrcp/tests/avrcp_test_helper.h
index 7a2f63ab2a..ea6ed4d828 100644
--- a/system/profile/avrcp/tests/avrcp_test_helper.h
+++ b/system/profile/avrcp/tests/avrcp_test_helper.h
@@ -80,7 +80,7 @@ public:
MOCK_METHOD4(FindService,
uint16_t(uint16_t, const RawAddress&, tAVRC_SDP_DB_PARAMS*, tAVRC_FIND_CBACK));
MOCK_METHOD3(Open, uint16_t(uint8_t*, tAVRC_CONN_CB*, const RawAddress&));
- MOCK_METHOD2(OpenBrowse, uint16_t(uint8_t, uint8_t));
+ MOCK_METHOD2(OpenBrowse, uint16_t(uint8_t, tAVCT_ROLE));
MOCK_METHOD1(GetPeerMtu, uint16_t(uint8_t));
MOCK_METHOD1(GetBrowseMtu, uint16_t(uint8_t));
MOCK_METHOD1(Close, uint16_t(uint8_t));
diff --git a/system/profile/sdp/Android.bp b/system/profile/sdp/Android.bp
deleted file mode 100644
index 88e491644f..0000000000
--- a/system/profile/sdp/Android.bp
+++ /dev/null
@@ -1,60 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_bt_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_bt_license"],
-}
-
-cc_library_static {
- name: "sdp_service",
- defaults: [
- "fluoride_defaults",
- ],
- host_supported: true,
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- ],
- srcs: [
- "common/data_element_reader.cc",
- ],
- static_libs: [
- "lib-bt-packets",
- "libbluetooth-types",
- "libbluetooth_log",
- ],
- header_libs: ["libbluetooth_headers"],
-}
-
-cc_test {
- name: "bluetooth_test_sdp",
- test_suites: ["general-tests"],
- defaults: [
- "fluoride_defaults",
- "mts_defaults",
- ],
- host_supported: true,
- include_dirs: [
- "packages/modules/Bluetooth/system/",
- "packages/modules/Bluetooth/system/gd",
- ],
- srcs: [
- "common/test/data_element_reader_test.cc",
- ],
- static_libs: [
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libbluetooth-types",
- "libbluetooth_log",
- "libchrome",
- "libgmock",
- "sdp_service",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
-}
diff --git a/system/profile/sdp/common/data_element_reader.cc b/system/profile/sdp/common/data_element_reader.cc
deleted file mode 100644
index 95c4d57e15..0000000000
--- a/system/profile/sdp/common/data_element_reader.cc
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright 2018 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 "data_element_reader.h"
-
-#include <bluetooth/log.h>
-
-#include <type_traits>
-
-#include "sdp_logging_helper.h"
-#include "types/bluetooth/uuid.h"
-
-// A helper macro that can verify that there is enough data remaining in the
-// reader to extract without overflowing. end_ - it_ should never be negative
-// so casting it to a size_t is always safe. If it does fail, set it_ to end_
-// so that all additional readings fail.
-#define CHECK_REMAINING_LEN(x) \
- do { \
- if ((size_t)(end_ - it_) < x) { \
- log::warn("Extract would read past end of data."); \
- return ParseFail(); \
- } \
- } while (0)
-
-namespace bluetooth {
-namespace sdp {
-
-DataElementReader::DataElement DataElementReader::ReadNext() {
- if (it_ > end_) {
- log::fatal("Beginning of buffer is past end of buffer.");
- }
- if (it_ == end_) {
- return std::monostate();
- }
-
- uint8_t descriptor = *it_++;
- DataElementType type = static_cast<DataElementType>(descriptor >> 3);
- DataElementSize size = static_cast<DataElementSize>(descriptor & 0b00000111);
-
- // All types with a value greater than URL are currently reserved.
- if (type > DataElementType::MAX_VALUE) {
- log::warn("Trying to use a reserved data element type");
- return ParseFail();
- }
-
- switch (type) {
- case DataElementType::BOOLEAN:
- if (size != DataElementSize::BYTE1) {
- log::warn("Invalid size for bool: {}", size);
- return ParseFail();
- }
-
- CHECK_REMAINING_LEN(1);
- return it_.extract<uint8_t>() != 0;
- case DataElementType::SIGNED_INT:
- return ReadSignedInt(size);
- case DataElementType::UNSIGNED_INT:
- return ReadUnsignedInt(size);
- case DataElementType::UUID:
- return ReadUuid(size);
- case DataElementType::STRING:
- return ReadString(size);
- case DataElementType::DATA_ELEMENT_SEQUENCE:
- return ReadSequence(size);
- default:
- // TODO: The other data element types are never used in the previous SDP
- // implementation. We should properly handle them in the future though
- // for completeness.
- log::error("Unhandled Data Element Type: {}", type);
- }
-
- return ParseFail();
-}
-
-DataElementReader::DataElement DataElementReader::ParseFail() {
- it_ = end_;
- return std::monostate();
-}
-
-template <class IntegerType>
-DataElementReader::DataElement DataElementReader::ReadInteger() {
- static_assert(std::is_integral<IntegerType>::value, "ReadInteger requires an integral type.");
-
- CHECK_REMAINING_LEN(sizeof(IntegerType));
- return it_.extractBE<IntegerType>();
-}
-
-DataElementReader::DataElement DataElementReader::ReadLargeInt() {
- CHECK_REMAINING_LEN(16);
-
- std::array<uint8_t, 16> array;
- for (size_t i = 0; i < sizeof(uint8_t[16]); i++) {
- array[i] = it_.extract<uint8_t>();
- }
-
- return array;
-}
-
-DataElementReader::DataElement DataElementReader::ReadSignedInt(DataElementSize size) {
- switch (size) {
- case DataElementSize::BYTE1:
- return ReadInteger<int8_t>();
- case DataElementSize::BYTE2:
- return ReadInteger<int16_t>();
- case DataElementSize::BYTE4:
- return ReadInteger<int32_t>();
- case DataElementSize::BYTE8:
- return ReadInteger<int64_t>();
- case DataElementSize::BYTE16:
- return ReadLargeInt();
- default:
- log::warn("Invalid size for int: {}", size);
- }
-
- return ParseFail();
-}
-
-DataElementReader::DataElement DataElementReader::ReadUnsignedInt(DataElementSize size) {
- switch (size) {
- case DataElementSize::BYTE1:
- return ReadInteger<uint8_t>();
- case DataElementSize::BYTE2:
- return ReadInteger<uint16_t>();
- case DataElementSize::BYTE4:
- return ReadInteger<uint32_t>();
- case DataElementSize::BYTE8:
- return ReadInteger<uint64_t>();
- case DataElementSize::BYTE16:
- return ReadLargeInt();
- default:
- log::warn("Invalid size for uint: {}", size);
- }
-
- return ParseFail();
-}
-
-DataElementReader::DataElement DataElementReader::ReadUuid(DataElementSize size) {
- if (size == DataElementSize::BYTE2) {
- CHECK_REMAINING_LEN(2);
- return Uuid::From16Bit(it_.extractBE<uint16_t>());
- }
-
- if (size == DataElementSize::BYTE4) {
- CHECK_REMAINING_LEN(4);
- return Uuid::From32Bit(it_.extractBE<uint32_t>());
- }
-
- if (size == DataElementSize::BYTE16) {
- CHECK_REMAINING_LEN(16);
-
- Uuid::UUID128Bit uuid_array;
- for (int i = 0; i < 16; i++) {
- uuid_array[i] = it_.extract<uint8_t>();
- }
-
- return Uuid::From128BitBE(uuid_array);
- }
-
- log::warn("Invalid size for UUID: {}", size);
- return ParseFail();
-}
-
-DataElementReader::DataElement DataElementReader::ReadString(DataElementSize size) {
- uint32_t num_bytes = 0;
-
- switch (size) {
- case DataElementSize::ADDITIONAL_8BIT:
- CHECK_REMAINING_LEN(1);
- num_bytes = it_.extractBE<uint8_t>();
- break;
- case DataElementSize::ADDITIONAL_16BIT:
- CHECK_REMAINING_LEN(2);
- num_bytes = it_.extractBE<uint16_t>();
- break;
- case DataElementSize::ADDITIONAL_32BIT:
- CHECK_REMAINING_LEN(4);
- num_bytes = it_.extractBE<uint32_t>();
- break;
- default:
- log::warn("Invalid size for string: {}", size);
- return ParseFail();
- }
-
- CHECK_REMAINING_LEN(num_bytes);
-
- std::string str;
- for (uint32_t i = 0; i < num_bytes; i++) {
- str.push_back(it_.extractBE<uint8_t>());
- }
-
- return str;
-}
-
-DataElementReader::DataElement DataElementReader::ReadSequence(DataElementSize size) {
- uint32_t num_bytes = 0;
-
- switch (size) {
- case DataElementSize::ADDITIONAL_8BIT:
- CHECK_REMAINING_LEN(1);
- num_bytes = it_.extractBE<uint8_t>();
- break;
- case DataElementSize::ADDITIONAL_16BIT:
- CHECK_REMAINING_LEN(2);
- num_bytes = it_.extractBE<uint16_t>();
- break;
- case DataElementSize::ADDITIONAL_32BIT:
- CHECK_REMAINING_LEN(4);
- num_bytes = it_.extractBE<uint32_t>();
- break;
- default:
- log::warn("Invalid size for string: {}", size);
- return ParseFail();
- }
-
- CHECK_REMAINING_LEN(num_bytes);
-
- // Create a parser that points to the beginning of the next sequence and move
- // the iterator to past the end of the new sequence.
- auto&& temp = DataElementReader(it_, it_ + num_bytes);
- it_ += num_bytes;
- return std::move(temp);
-}
-
-} // namespace sdp
-} // namespace bluetooth
diff --git a/system/profile/sdp/common/data_element_reader.h b/system/profile/sdp/common/data_element_reader.h
deleted file mode 100644
index eea58ece43..0000000000
--- a/system/profile/sdp/common/data_element_reader.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-#pragma once
-
-#include <array>
-#include <variant>
-
-#include "bluetooth/uuid.h"
-#include "packet.h"
-#include "sdp_common.h"
-#include "stack/include/bt_octets.h"
-
-namespace bluetooth {
-namespace sdp {
-
-// A helper class that helps extract data element objects from SDP packets.
-class DataElementReader {
-public:
- // If the DataElement contains monostate, that means parsing has failed.
- using DataElement =
- std::variant<std::monostate, bool, int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t,
- uint32_t, uint64_t, Octet16, Uuid, std::string, DataElementReader>;
-
- DataElementReader(Iterator begin, Iterator end) : it_(begin), end_(end) {}
-
- // Get the next Data Element in the data. If reading fails for any reason,
- // the DataElementReader becomes invalid and will continuously fail to read
- // from that point onward.
- DataElement ReadNext();
-
-private:
- // Extraction Helpers
- DataElement ParseFail();
- template <class IntegerType>
- DataElement ReadInteger();
- DataElement ReadLargeInt();
-
- // Extraction Functions
- DataElement ReadSignedInt(DataElementSize size);
- DataElement ReadUnsignedInt(DataElementSize size);
- DataElement ReadUuid(DataElementSize size);
- DataElement ReadString(DataElementSize size);
- DataElement ReadSequence(DataElementSize size);
-
- Iterator it_;
- Iterator end_;
-};
-
-} // namespace sdp
-} // namespace bluetooth
diff --git a/system/profile/sdp/common/test/data_element_reader_test.cc b/system/profile/sdp/common/test/data_element_reader_test.cc
deleted file mode 100644
index 3203098e0d..0000000000
--- a/system/profile/sdp/common/test/data_element_reader_test.cc
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright 2018 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 "common/data_element_reader.h"
-
-#include <gtest/gtest.h>
-
-#include "types/bluetooth/uuid.h"
-
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
-namespace bluetooth {
-namespace sdp {
-
-using namespace testing;
-using DataElement = DataElementReader::DataElement;
-
-// A helper class to help work with the Data Element classes.
-class ReaderPacket : public ::bluetooth::Packet {
-public:
- using Packet::Packet;
-
- static std::shared_ptr<ReaderPacket> Make(std::vector<uint8_t> payload) {
- auto pkt = std::shared_ptr<ReaderPacket>(new ReaderPacket());
- pkt->packet_start_index_ = 0;
- pkt->packet_end_index_ = payload.size();
- pkt->data_ = std::make_shared<std::vector<uint8_t>>(std::move(payload));
- return pkt;
- }
-
- std::string ToString() const override { return ""; }
- bool IsValid() const override { return true; }
- std::pair<size_t, size_t> GetPayloadIndecies() const override {
- return std::pair<size_t, size_t>(packet_start_index_, packet_end_index_);
- }
-};
-
-bool operator!=(DataElementReader a, DataElementReader b);
-
-// A helper function to help compare DataElementReader objects.
-bool operator==(DataElementReader a, DataElementReader b) {
- while (true) {
- DataElement a_elem = a.ReadNext();
- DataElement b_elem = b.ReadNext();
-
- if (a_elem != b_elem) {
- return false;
- }
-
- // If we get here that means both a and b have reached the end.
- if (a_elem == DataElement(std::monostate())) {
- break;
- }
- }
-
- return true;
-}
-
-bool operator!=(DataElementReader a, DataElementReader b) { return !(a == b); }
-
-// A helper function to convert a type and a size to a descriptor byte.
-constexpr uint8_t Desc(DataElementType t, DataElementSize s) {
- return static_cast<uint8_t>(t) << 3 | static_cast<uint8_t>(s);
-}
-
-// Helper that can create a Data Element reader from a vector.
-DataElementReader CreateReader(std::vector<uint8_t> payload) {
- auto packet = ReaderPacket::Make(std::move(payload));
- return DataElementReader(packet->begin(), packet->end());
-}
-
-// Test all the valid cases of reading the next Data Element.
-using ValidTestParam = std::tuple<std::vector<uint8_t>, DataElement>;
-class ValidReadTest : public TestWithParam<ValidTestParam> {};
-
-std::vector<ValidTestParam> valid_values = {
- // Boolean Tests
- ValidTestParam{
- {Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01},
- true,
- },
- ValidTestParam{
- {Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00},
- false,
- },
-
- // Signed Integer Tests
- ValidTestParam{{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE1), 0xFF},
- static_cast<int8_t>(-1)},
- ValidTestParam{{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE2), 0xFF, 0xFF},
- static_cast<int16_t>(-1)},
- ValidTestParam{
- {Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE4), 0xFF, 0xFF, 0xFF, 0xFF},
- static_cast<int32_t>(-1)},
- ValidTestParam{{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE8), 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- static_cast<int64_t>(-1)},
- ValidTestParam{
- {Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE16), 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
- std::array<uint8_t, 16>{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
-
- // Unsigned Integer Tests
- ValidTestParam{{Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE1), 0x01},
- static_cast<uint8_t>(1)},
- ValidTestParam{{Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE2), 0x00, 0x01},
- static_cast<uint16_t>(1)},
- ValidTestParam{{Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE4), 0x00, 0x00,
- 0x00, 0x01},
- static_cast<uint32_t>(1)},
- ValidTestParam{{Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE8), 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
- static_cast<uint64_t>(1)},
- ValidTestParam{
- {Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE16), 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
- std::array<uint8_t, 16>{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}},
-
- // UUID Tests
- ValidTestParam{{Desc(DataElementType::UUID, DataElementSize::BYTE2), 0x01, 0x02},
- Uuid::From16Bit(0x0102)},
- ValidTestParam{
- {Desc(DataElementType::UUID, DataElementSize::BYTE4), 0x01, 0x02, 0x03, 0x04},
- Uuid::From32Bit(0x01020304)},
- ValidTestParam{
- {Desc(DataElementType::UUID, DataElementSize::BYTE16), 0x00, 0x01, 0x02, 0x03, 0x04,
- 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
- Uuid::From128BitBE({0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
- 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F})},
-
- // String Tests
- ValidTestParam{{Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_8BIT), 0x05, 'T',
- 'e', 's', 't', '1'},
- std::string("Test1")},
- ValidTestParam{{Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_16BIT), 0x00,
- 0x05, 'T', 'e', 's', 't', '2'},
- std::string("Test2")},
- ValidTestParam{{Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_32BIT), 0x00,
- 0x00, 0x00, 0x05, 'T', 'e', 's', 't', '3'},
- std::string("Test3")},
-
- // Nested Data Element List Tests
- ValidTestParam{
- {Desc(DataElementType::DATA_ELEMENT_SEQUENCE, DataElementSize::ADDITIONAL_8BIT),
- 0x04, Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01,
- Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00},
- CreateReader({Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01,
- Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00})},
- ValidTestParam{
- {Desc(DataElementType::DATA_ELEMENT_SEQUENCE, DataElementSize::ADDITIONAL_16BIT),
- 0x00, 0x04, Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01,
- Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00},
- CreateReader({Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01,
- Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00})},
- ValidTestParam{
- {Desc(DataElementType::DATA_ELEMENT_SEQUENCE, DataElementSize::ADDITIONAL_32BIT),
- 0x00, 0x00, 0x00, 0x04, Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1),
- 0x01, Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00},
- CreateReader({Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01,
- Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00})},
-};
-
-INSTANTIATE_TEST_CASE_P(ReadNext, ValidReadTest, ValuesIn(valid_values));
-TEST_P(ValidReadTest, Test) {
- auto packet = ReaderPacket::Make(std::get<0>(GetParam()));
- auto value = std::get<1>(GetParam());
-
- DataElementReader reader(packet->begin(), packet->end());
- auto read_value = reader.ReadNext();
-
- ASSERT_EQ(value, read_value);
-
- // Test that there is no additional data to read.
- ASSERT_EQ(reader.ReadNext(), DataElement(std::monostate()));
-}
-
-// Test that a nested reader is correctly bounded and can't read past its
-// defined end.
-TEST(ReadNext, BoundedSubreaderTest) {
- std::vector<uint8_t> payload = {
- // Subsequence descriptor byte.
- Desc(DataElementType::DATA_ELEMENT_SEQUENCE, DataElementSize::ADDITIONAL_8BIT),
- // Subsequence length.
- 0x04,
- // Subsequence that contains two booleans with values true and false.
- Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x01,
- Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1), 0x00,
- // Additional int16 at the end of the original sequence.
- Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE2), 0x01, 0x23};
-
- auto packet = ReaderPacket::Make(payload);
- DataElementReader reader(packet->begin(), packet->end());
-
- // The first thing read should be the subsequence.
- auto data_element = reader.ReadNext();
- ASSERT_TRUE(std::holds_alternative<DataElementReader>(data_element));
-
- // Check that the subsequence matches the premade sequence.
- auto subreader = std::get<DataElementReader>(data_element);
- data_element = subreader.ReadNext();
- ASSERT_TRUE(std::holds_alternative<bool>(data_element));
- ASSERT_TRUE(std::get<bool>(data_element));
- data_element = subreader.ReadNext();
- ASSERT_TRUE(std::holds_alternative<bool>(data_element));
- ASSERT_FALSE(std::get<bool>(data_element));
-
- // Check that there is no additional data to be read from the subreader.
- ASSERT_EQ(subreader.ReadNext(), DataElement(std::monostate()));
-
- // Check that we can still read the int16 from the original reader.
- data_element = reader.ReadNext();
- ASSERT_TRUE(std::holds_alternative<int16_t>(data_element));
- auto int16_value = std::get<int16_t>(data_element);
- ASSERT_EQ(int16_value, 0x0123);
-
- // Check that there is no additional data to be read from the base reader.
- ASSERT_EQ(reader.ReadNext(), DataElement(std::monostate()));
-}
-
-// Test that trying to read an empty packet fails.
-TEST(ReadNext, NoDataTest) {
- auto packet = ReaderPacket::Make({});
- DataElementReader reader(packet->begin(), packet->end());
-
- ASSERT_EQ(reader.ReadNext(), DataElement(std::monostate()));
-}
-
-// Test that using a reserved value for type fails.
-TEST(ReadNext, InvalidTypeTest) {
- auto packet = ReaderPacket::Make({0xFF});
- DataElementReader reader(packet->begin(), packet->end());
-
- ASSERT_EQ(reader.ReadNext(), DataElement(std::monostate()));
-}
-
-// Test all invalid parses due to incorrect lengths or invalid sizes. All tests
-// should return std::monostate.
-using InvalidTestParam = std::vector<uint8_t>;
-class InvalidReadTest : public TestWithParam<InvalidTestParam> {};
-
-std::vector<InvalidTestParam> invalid_values = {
- // Boolean Tests:
- // Invalid size field.
- InvalidTestParam{
- Desc(DataElementType::BOOLEAN, DataElementSize::BYTE2),
- },
- // Insufficient data.
- InvalidTestParam{Desc(DataElementType::BOOLEAN, DataElementSize::BYTE1)},
-
- // Signed Integer Tests:
- // Invalid size field.
- InvalidTestParam{Desc(DataElementType::SIGNED_INT, DataElementSize::ADDITIONAL_8BIT)},
- // 1 byte insufficient data.
- InvalidTestParam{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE1)},
- // 2 byte insufficient data.
- InvalidTestParam{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE2), 0x00},
- // 4 byte insufficient data.
- InvalidTestParam{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE4), 0x00, 0x00,
- 0x00},
- // 8 Byte insufficient data.
- InvalidTestParam{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE8), 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00},
- // 16 Byte insufficient data.
- InvalidTestParam{Desc(DataElementType::SIGNED_INT, DataElementSize::BYTE16), 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-
- // Unsigned Integer Tests:
- // Invalid size field.
- InvalidTestParam{Desc(DataElementType::UNSIGNED_INT, DataElementSize::ADDITIONAL_8BIT)},
- // 1 byte insufficient data.
- InvalidTestParam{Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE1)},
- // 2 byte insufficient data.
- InvalidTestParam{Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE2), 0x00},
- // 4 byte insufficient data.
- InvalidTestParam{Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE4), 0x00, 0x00,
- 0x00},
- // 8 Byte insufficient data.
- InvalidTestParam{Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE8), 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00},
- // 16 Byte insufficient data.
- InvalidTestParam{Desc(DataElementType::UNSIGNED_INT, DataElementSize::BYTE16), 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-
- // UUID Tests:
- // Invalid size field.
- InvalidTestParam{Desc(DataElementType::UUID, DataElementSize::ADDITIONAL_8BIT)},
- // 2 byte insufficient data.
- InvalidTestParam{Desc(DataElementType::UUID, DataElementSize::BYTE2), 0x00},
- // 4 byte insufficient data.
- InvalidTestParam{Desc(DataElementType::UUID, DataElementSize::BYTE4), 0x00, 0x00, 0x00},
- // 16 Byte insufficient data.
- InvalidTestParam{Desc(DataElementType::UUID, DataElementSize::BYTE16), 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-
- // String Tests:
- // Invalid size field.
- InvalidTestParam{Desc(DataElementType::STRING, DataElementSize::BYTE1)},
- // Insufficient data for additional 8 bits len.
- InvalidTestParam{Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_8BIT)},
- // Insufficient data for additional 16 bits len.
- InvalidTestParam{
- Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_16BIT),
- 0x00,
- },
- // Insufficient data for additional 32 bit len.
- InvalidTestParam{
- Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_32BIT),
- 0x00,
- 0x00,
- 0x00,
- },
- // Insufficient data for reported length.
- InvalidTestParam{Desc(DataElementType::STRING, DataElementSize::ADDITIONAL_8BIT), 0x04, '1',
- '2', '3'},
-
- // Nested Data Element List Tests:
- // Invalid size field.
- InvalidTestParam{Desc(DataElementType::DATA_ELEMENT_SEQUENCE, DataElementSize::BYTE1)},
- // Insufficient data for additional 8 bits len.
- InvalidTestParam{
- Desc(DataElementType::DATA_ELEMENT_SEQUENCE, DataElementSize::ADDITIONAL_8BIT)},
- // Insufficient data for additional 16 bits len.
- InvalidTestParam{
- Desc(DataElementType::DATA_ELEMENT_SEQUENCE, DataElementSize::ADDITIONAL_16BIT),
- 0x00,
- },
- // Insufficient data for additional 32 bit len.
- InvalidTestParam{
- Desc(DataElementType::DATA_ELEMENT_SEQUENCE, DataElementSize::ADDITIONAL_32BIT),
- 0x00,
- 0x00,
- 0x00,
- },
- // Insufficient data for reported length.
- InvalidTestParam{
- Desc(DataElementType::DATA_ELEMENT_SEQUENCE, DataElementSize::ADDITIONAL_8BIT),
- 0x04, 0x00, 0x00, 0x00},
-
- // Unhandled Data Element Types Tests:
- // NOTE: These tests should go away as we begin to handle the types.
- // Nil Type.
- InvalidTestParam{Desc(DataElementType::NIL, DataElementSize::BYTE1)},
- // Data Element Alternative List Type.
- InvalidTestParam{
- Desc(DataElementType::DATA_ELEMENT_ALTERNATIVE, DataElementSize::ADDITIONAL_8BIT),
- 0x00},
- // URL Type.
- InvalidTestParam{Desc(DataElementType::URL, DataElementSize::ADDITIONAL_8BIT), 0x00}};
-
-INSTANTIATE_TEST_CASE_P(ReadNext, InvalidReadTest, ValuesIn(invalid_values));
-TEST_P(InvalidReadTest, Test) {
- auto packet = ReaderPacket::Make(GetParam());
- DataElementReader reader(packet->begin(), packet->end());
-
- ASSERT_EQ(reader.ReadNext(), DataElement(std::monostate()));
-}
-
-// Test that trying to read from a reader with start > end crashes.
-TEST(DataElementReader, BadBoundsDeathTest) {
- auto packet = ReaderPacket::Make({0x00, 0x00, 0x00, 0x00});
- DataElementReader reader(packet->end(), packet->begin());
- ASSERT_DEATH(reader.ReadNext(), "Beginning of buffer is past end of buffer.");
-}
-
-} // namespace sdp
-} // namespace bluetooth
diff --git a/system/profile/sdp/sdp_common.h b/system/profile/sdp/sdp_common.h
deleted file mode 100644
index 4a07a6306d..0000000000
--- a/system/profile/sdp/sdp_common.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-#pragma once
-
-namespace bluetooth {
-namespace sdp {
-
-enum class PduId : uint8_t {
- RESERVED = 0x00,
- ERROR = 0x01,
- SERVICE_SEARCH_REQUEST = 0x02,
- SERVICE_SEARCH_RESPONSE = 0x03,
- SERVICE_ATTRIBUTE_REQUEST = 0x04,
- SERVICE_ATTRIBUTE_RESPONSE = 0x05,
- SERVICE_SEARCH_ATTRIBUTE_REQUEST = 0x06,
- SERVICE_SEARCH_ATTRIBUTE_RESPONSE = 0x07,
- MAX_VALUE = 0x07,
-};
-
-enum class AttributeId : uint16_t {
- SERVICE_RECORD_HANDLE = 0x0000,
- SERVICE_CLASS_ID_LIST = 0x0001,
- SERVICE_RECORD_STATE = 0x0002,
- SERVICE_ID = 0x0003,
- PROTOCOL_DESCRIPTOR_LIST = 0x0004,
- BROWSE_GROUP_LIST = 0x0005,
- LANGUAGE_BASE_ATTRIBUTE_ID_LIST = 0x0006,
- SERVICE_INFO_TIME_TO_LIVE = 0x0007,
- SERVICE_AVAILABILITY = 0x0008,
- PROFILE_DESCRIPTOR_LIST = 0x0009,
- DOCUMENTATION_URL = 0x000A,
- CLIENT_EXECUTABLE_URL = 0x000B,
- ICON_URL = 0x000C,
- ADDITIONAL_PROTOCOL_DESCRIPTOR_LIST = 0x000D,
-
- // The following attributes are only used in the SDP server service record.
- // They are only valid if ServiceDiscoveryServerServiceClassID is in the
- // ServiceClassIDList. See Bluetooth Core v5.0 Section 5.2.
- VERSION_NUMBER_LIST = 0x0200,
- SERVICE_DATABASE_STATE = 0x0201,
-};
-
-// The Attribute ID's of these attributes are calculated by adding the offset
-// value for the attribute to the attribute ID base (contained in the
-// LanguageBaseAttributeIDList attribute value).
-enum AttributeIdOffset : uint16_t {
- SERVICE_NAME = 0x0000,
- SERVICE_DESCRIPTION = 0x0001,
- PROVIDER_NAME = 0x0002,
-};
-
-// Constant that define the different types of data element.
-enum class DataElementType : uint8_t {
- NIL = 0x00,
- UNSIGNED_INT = 0x01,
- SIGNED_INT = 0x02,
- UUID = 0x03,
- STRING = 0x04,
- BOOLEAN = 0x05,
- DATA_ELEMENT_SEQUENCE = 0x06,
- DATA_ELEMENT_ALTERNATIVE = 0x07,
- URL = 0x08,
- MAX_VALUE = 0x08,
-};
-
-// Constant that define the different sizes of data element.
-enum class DataElementSize : uint8_t {
- BYTE1 = 0x0, // Exception: If the data element is NIL then size is 0 bytes
- BYTE2 = 0x1,
- BYTE4 = 0x2,
- BYTE8 = 0x3,
- BYTE16 = 0x4,
- // The size types below represent that the first X bits of the value
- // represents the size of the remaining data.
- ADDITIONAL_8BIT = 0x5,
- ADDITIONAL_16BIT = 0x6,
- ADDITIONAL_32BIT = 0x7,
-};
-
-} // namespace sdp
-} // namespace bluetooth
diff --git a/system/profile/sdp/sdp_logging_helper.h b/system/profile/sdp/sdp_logging_helper.h
deleted file mode 100644
index 4a8d178296..0000000000
--- a/system/profile/sdp/sdp_logging_helper.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-#pragma once
-
-#include <bluetooth/log.h>
-
-#include <iomanip>
-#include <iostream>
-#include <sstream>
-#include <string>
-#include <type_traits>
-
-#include "macros.h"
-#include "sdp_common.h"
-
-namespace bluetooth {
-namespace sdp {
-
-inline std::string PduIdText(const PduId& id) {
- switch (id) {
- CASE_RETURN_TEXT(PduId::RESERVED);
- CASE_RETURN_TEXT(PduId::ERROR);
- CASE_RETURN_TEXT(PduId::SERVICE_SEARCH_REQUEST);
- CASE_RETURN_TEXT(PduId::SERVICE_SEARCH_RESPONSE);
- CASE_RETURN_TEXT(PduId::SERVICE_ATTRIBUTE_REQUEST);
- CASE_RETURN_TEXT(PduId::SERVICE_ATTRIBUTE_RESPONSE);
- CASE_RETURN_TEXT(PduId::SERVICE_SEARCH_ATTRIBUTE_REQUEST);
- CASE_RETURN_TEXT(PduId::SERVICE_SEARCH_ATTRIBUTE_RESPONSE);
- default:
- return fmt::format("Unknown PduId: 0x{:x}", (uint8_t)id);
- }
-}
-
-inline std::ostream& operator<<(std::ostream& os, const PduId& id) { return os << PduIdText(id); }
-
-inline std::string AttributeIdText(const AttributeId& id) {
- switch (id) {
- CASE_RETURN_TEXT(AttributeId::SERVICE_RECORD_HANDLE);
- CASE_RETURN_TEXT(AttributeId::SERVICE_CLASS_ID_LIST);
- CASE_RETURN_TEXT(AttributeId::SERVICE_RECORD_STATE);
- CASE_RETURN_TEXT(AttributeId::SERVICE_ID);
- CASE_RETURN_TEXT(AttributeId::PROTOCOL_DESCRIPTOR_LIST);
- CASE_RETURN_TEXT(AttributeId::BROWSE_GROUP_LIST);
- CASE_RETURN_TEXT(AttributeId::LANGUAGE_BASE_ATTRIBUTE_ID_LIST);
- CASE_RETURN_TEXT(AttributeId::SERVICE_INFO_TIME_TO_LIVE);
- CASE_RETURN_TEXT(AttributeId::SERVICE_AVAILABILITY);
- CASE_RETURN_TEXT(AttributeId::PROFILE_DESCRIPTOR_LIST);
- CASE_RETURN_TEXT(AttributeId::DOCUMENTATION_URL);
- CASE_RETURN_TEXT(AttributeId::CLIENT_EXECUTABLE_URL);
- CASE_RETURN_TEXT(AttributeId::ICON_URL);
- CASE_RETURN_TEXT(AttributeId::ADDITIONAL_PROTOCOL_DESCRIPTOR_LIST);
- CASE_RETURN_TEXT(AttributeId::VERSION_NUMBER_LIST);
- CASE_RETURN_TEXT(AttributeId::SERVICE_DATABASE_STATE);
- default:
- return fmt::format("Unknown AttributeId: 0x{:x}", (uint16_t)id);
- }
-}
-
-inline std::ostream& operator<<(std::ostream& os, const AttributeId& id) {
- return os << AttributeIdText(id);
-}
-
-inline std::string DataElementTypeText(const DataElementType& type) {
- switch (type) {
- CASE_RETURN_TEXT(DataElementType::NIL);
- CASE_RETURN_TEXT(DataElementType::UNSIGNED_INT);
- CASE_RETURN_TEXT(DataElementType::SIGNED_INT);
- CASE_RETURN_TEXT(DataElementType::UUID);
- CASE_RETURN_TEXT(DataElementType::STRING);
- CASE_RETURN_TEXT(DataElementType::BOOLEAN);
- CASE_RETURN_TEXT(DataElementType::DATA_ELEMENT_SEQUENCE);
- CASE_RETURN_TEXT(DataElementType::DATA_ELEMENT_ALTERNATIVE);
- CASE_RETURN_TEXT(DataElementType::URL);
- default:
- return fmt::format("Unknown DataElementType: 0x{:x}", (uint8_t)type);
- }
-}
-
-inline std::ostream& operator<<(std::ostream& os, const DataElementType& type) {
- return os << DataElementTypeText(type);
-}
-
-inline std::string DataElementSizeText(const DataElementSize& size) {
- switch (size) {
- CASE_RETURN_TEXT(DataElementSize::BYTE1);
- CASE_RETURN_TEXT(DataElementSize::BYTE2);
- CASE_RETURN_TEXT(DataElementSize::BYTE4);
- CASE_RETURN_TEXT(DataElementSize::BYTE8);
- CASE_RETURN_TEXT(DataElementSize::BYTE16);
- CASE_RETURN_TEXT(DataElementSize::ADDITIONAL_8BIT);
- CASE_RETURN_TEXT(DataElementSize::ADDITIONAL_16BIT);
- CASE_RETURN_TEXT(DataElementSize::ADDITIONAL_32BIT);
- default:
- return fmt::format("Unknown DataElementSize: 0x{:x}", (uint8_t)size);
- }
-}
-
-inline std::ostream& operator<<(std::ostream& os, const DataElementSize& size) {
- return os << DataElementSizeText(size);
-}
-
-} // namespace sdp
-} // namespace bluetooth
-
-namespace fmt {
-template <>
-struct formatter<bluetooth::sdp::PduId> : ostream_formatter {};
-template <>
-struct formatter<bluetooth::sdp::AttributeId> : ostream_formatter {};
-template <>
-struct formatter<bluetooth::sdp::DataElementType> : ostream_formatter {};
-template <>
-struct formatter<bluetooth::sdp::DataElementSize> : ostream_formatter {};
-} // namespace fmt
diff --git a/system/rust/src/core/ffi/module.cc b/system/rust/src/core/ffi/module.cc
index 5e79d143fa..edd2b13b58 100644
--- a/system/rust/src/core/ffi/module.cc
+++ b/system/rust/src/core/ffi/module.cc
@@ -20,7 +20,7 @@
#include <hardware/bt_gatt.h>
#include "btcore/include/module.h"
-#include "os/log.h"
+
#ifndef TARGET_FLOSS
#include "src/core/ffi.rs.h"
#include "src/gatt/ffi.rs.h"
diff --git a/system/rust/src/gatt/ffi/gatt_shim.cc b/system/rust/src/gatt/ffi/gatt_shim.cc
index 3b17f83cda..442c5b5fa4 100644
--- a/system/rust/src/gatt/ffi/gatt_shim.cc
+++ b/system/rust/src/gatt/ffi/gatt_shim.cc
@@ -26,7 +26,6 @@
#include "include/hardware/bt_common_types.h"
#include "include/hardware/bt_gatt_client.h"
#include "include/hardware/bt_gatt_server.h"
-#include "os/log.h"
#include "rust/cxx.h"
#include "stack/include/gatt_api.h"
#include "types/bluetooth/uuid.h"
diff --git a/system/stack/Android.bp b/system/stack/Android.bp
index 5fec9d2cee..25cf3c5a5d 100644
--- a/system/stack/Android.bp
+++ b/system/stack/Android.bp
@@ -275,11 +275,11 @@ cc_library_static {
"btm/security_event_parser.cc",
"btu/btu_event.cc",
"btu/btu_hcif.cc",
+ "connection_manager/connection_manager.cc",
"eatt/eatt.cc",
"gap/gap_ble.cc",
"gap/gap_conn.cc",
"gatt/att_protocol.cc",
- "gatt/connection_manager.cc",
"gatt/gatt_api.cc",
"gatt/gatt_attr.cc",
"gatt/gatt_auth.cc",
@@ -540,6 +540,7 @@ cc_fuzz {
":TestMockStackAcl",
":TestMockStackArbiter",
":TestMockStackBtm",
+ ":TestMockStackConnMgr",
":TestMockStackHcic",
":TestMockStackL2cap",
":TestMockStackMetrics",
@@ -1067,7 +1068,7 @@ cc_test {
// Bluetooth stack connection multiplexing
cc_test {
- name: "net_test_gatt_conn_multiplexing",
+ name: "net_test_conn_multiplexing",
defaults: [
"fluoride_defaults",
"mts_defaults",
@@ -1086,9 +1087,9 @@ cc_test {
srcs: [
":TestCommonMainHandler",
":TestMockStackBtmInterface",
- "gatt/connection_manager.cc",
+ "connection_manager/connection_manager.cc",
"test/common/mock_btm_api_layer.cc",
- "test/gatt_connection_manager_test.cc",
+ "test/connection_manager_test.cc",
],
shared_libs: [
"libcutils",
@@ -1180,6 +1181,76 @@ cc_test {
}
cc_test {
+ name: "net_test_stack_avctp",
+ defaults: [
+ "fluoride_defaults",
+ "mts_defaults",
+ ],
+ test_suites: ["general-tests"],
+ host_supported: true,
+ test_options: {
+ unit_test: true,
+ },
+ include_dirs: [
+ "external/libldac/inc",
+ "packages/modules/Bluetooth/system",
+ "packages/modules/Bluetooth/system/gd",
+ "packages/modules/Bluetooth/system/stack/include",
+ ],
+ srcs: [
+ ":TestCommonMockFunctions",
+ ":TestFakeOsi",
+ ":TestMockBta",
+ ":TestMockBtif",
+ ":TestMockDevice",
+ ":TestMockStackA2dp",
+ ":TestMockStackAcl",
+ ":TestMockStackL2cap",
+ "avct/avct_api.cc",
+ "avct/avct_bcb_act.cc",
+ "avct/avct_ccb.cc",
+ "avct/avct_l2c.cc",
+ "avct/avct_l2c_br.cc",
+ "avct/avct_lcb.cc",
+ "avct/avct_lcb_act.cc",
+ "test/stack_avctp_test.cc",
+ ],
+ shared_libs: [
+ "libcrypto",
+ "libcutils",
+ "server_configurable_flags",
+ ],
+ static_libs: [
+ "bluetooth_flags_c_lib_for_test",
+ "libaconfig_storage_read_api_cc",
+ "libbase",
+ "libbluetooth-types",
+ "libbluetooth_crypto_toolbox",
+ "libbluetooth_gd",
+ "libbluetooth_log",
+ "libbt-common",
+ "libchrome",
+ "libevent",
+ "libgmock",
+ "liblog",
+ "libosi",
+ "libprotobuf-cpp-lite",
+ "libstatslog_bt",
+ ],
+ target: {
+ android: {
+ shared_libs: ["libstatssocket"],
+ },
+ },
+ sanitize: {
+ address: true,
+ cfi: true,
+ misc_undefined: ["bounds"],
+ },
+ header_libs: ["libbluetooth_headers"],
+}
+
+cc_test {
name: "net_test_stack_avdtp",
defaults: [
"fluoride_defaults",
@@ -1652,6 +1723,7 @@ cc_test {
":TestMockMainShimEntry",
":TestMockRustFfi",
":TestMockStackBtu",
+ ":TestMockStackConnMgr",
":TestMockStackGap",
":TestMockStackGatt",
":TestMockStackHcic",
@@ -1972,9 +2044,9 @@ cc_test {
":TestMockStackSmp",
"ais/ais_ble.cc",
"arbiter/acl_arbiter.cc",
+ "connection_manager/connection_manager.cc",
"eatt/eatt.cc",
"gatt/att_protocol.cc",
- "gatt/connection_manager.cc",
"gatt/gatt_api.cc",
"gatt/gatt_attr.cc",
"gatt/gatt_auth.cc",
@@ -2067,7 +2139,7 @@ cc_test {
":TestMockMainShimEntry",
":TestMockStackAcl",
":TestMockStackBtm",
- ":TestMockStackGatt",
+ ":TestMockStackConnMgr",
":TestMockStackHcic",
":TestMockStackSdp",
":TestMockStackSmp",
@@ -2164,6 +2236,7 @@ cc_test {
":TestMockRustFfi",
":TestMockStackBtm",
":TestMockStackBtu",
+ ":TestMockStackConnMgr",
":TestMockStackGatt",
":TestMockStackHcic",
":TestMockStackL2cap",
diff --git a/system/stack/BUILD.gn b/system/stack/BUILD.gn
index c2b87b44a5..559aa1f366 100644
--- a/system/stack/BUILD.gn
+++ b/system/stack/BUILD.gn
@@ -125,7 +125,7 @@ source_set("stack") {
"gap/gap_ble.cc",
"gap/gap_conn.cc",
"gatt/att_protocol.cc",
- "gatt/connection_manager.cc",
+ "connection_manager/connection_manager.cc",
"gatt/gatt_api.cc",
"gatt/gatt_attr.cc",
"gatt/gatt_auth.cc",
diff --git a/system/stack/a2dp/a2dp_aac.cc b/system/stack/a2dp/a2dp_aac.cc
index 1784e824c5..ca0dec4037 100644
--- a/system/stack/a2dp/a2dp_aac.cc
+++ b/system/stack/a2dp/a2dp_aac.cc
@@ -31,7 +31,6 @@
#include "a2dp_aac_decoder.h"
#include "a2dp_aac_encoder.h"
#include "internal_include/bt_trace.h"
-#include "os/log.h"
#include "osi/include/osi.h"
#include "osi/include/properties.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/a2dp/a2dp_aac_decoder.cc b/system/stack/a2dp/a2dp_aac_decoder.cc
index e1fb4f4929..fba7ea44cf 100644
--- a/system/stack/a2dp/a2dp_aac_decoder.cc
+++ b/system/stack/a2dp/a2dp_aac_decoder.cc
@@ -21,7 +21,6 @@
#include <aacdecoder_lib.h>
#include <bluetooth/log.h>
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/a2dp/a2dp_aac_encoder.cc b/system/stack/a2dp/a2dp_aac_encoder.cc
index d322d7f8cf..774fdd92ae 100644
--- a/system/stack/a2dp/a2dp_aac_encoder.cc
+++ b/system/stack/a2dp/a2dp_aac_encoder.cc
@@ -26,7 +26,6 @@
#include "a2dp_aac.h"
#include "common/time_util.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/a2dp/a2dp_sbc_encoder.cc b/system/stack/a2dp/a2dp_sbc_encoder.cc
index c0c923ec82..e5cb555262 100644
--- a/system/stack/a2dp/a2dp_sbc_encoder.cc
+++ b/system/stack/a2dp/a2dp_sbc_encoder.cc
@@ -25,11 +25,14 @@
#include <limits.h>
#include <string.h>
+#include <cinttypes>
+
#include "a2dp_sbc.h"
#include "a2dp_sbc_up_sample.h"
#include "common/time_util.h"
#include "embdrv/sbc/encoder/include/sbc_encoder.h"
#include "internal_include/bt_target.h"
+#include "os/logging/log_adapter.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/a2dp/a2dp_vendor_aptx_encoder.cc b/system/stack/a2dp/a2dp_vendor_aptx_encoder.cc
index 969a06643d..7bb81bf244 100644
--- a/system/stack/a2dp/a2dp_vendor_aptx_encoder.cc
+++ b/system/stack/a2dp/a2dp_vendor_aptx_encoder.cc
@@ -28,7 +28,6 @@
#include "aptXbtenc.h"
#include "common/time_util.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/a2dp/a2dp_vendor_aptx_hd.cc b/system/stack/a2dp/a2dp_vendor_aptx_hd.cc
index f6ed0c6cfa..cc59936638 100644
--- a/system/stack/a2dp/a2dp_vendor_aptx_hd.cc
+++ b/system/stack/a2dp/a2dp_vendor_aptx_hd.cc
@@ -32,7 +32,6 @@
#include "a2dp_vendor_aptx_hd_encoder.h"
#include "btif/include/btif_av_co.h"
#include "internal_include/bt_trace.h"
-#include "os/log.h"
#include "osi/include/osi.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc b/system/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc
index d6daf805a5..b6996d0108 100644
--- a/system/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc
+++ b/system/stack/a2dp/a2dp_vendor_aptx_hd_encoder.cc
@@ -28,7 +28,6 @@
#include "aptXHDbtenc.h"
#include "common/time_util.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/a2dp/a2dp_vendor_ldac.cc b/system/stack/a2dp/a2dp_vendor_ldac.cc
index b3ad871b31..8c1519eb65 100644
--- a/system/stack/a2dp/a2dp_vendor_ldac.cc
+++ b/system/stack/a2dp/a2dp_vendor_ldac.cc
@@ -32,7 +32,6 @@
#include "a2dp_vendor_ldac_encoder.h"
#include "btif/include/btif_av_co.h"
#include "internal_include/bt_trace.h"
-#include "os/log.h"
#include "osi/include/osi.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/a2dp/a2dp_vendor_ldac_decoder.cc b/system/stack/a2dp/a2dp_vendor_ldac_decoder.cc
index 4babdc79dc..4107e64e90 100644
--- a/system/stack/a2dp/a2dp_vendor_ldac_decoder.cc
+++ b/system/stack/a2dp/a2dp_vendor_ldac_decoder.cc
@@ -26,7 +26,6 @@
#include <string.h>
#include "a2dp_vendor_ldac.h"
-#include "os/log.h"
#include "stack/include/bt_hdr.h"
using namespace bluetooth;
diff --git a/system/stack/a2dp/a2dp_vendor_ldac_encoder.cc b/system/stack/a2dp/a2dp_vendor_ldac_encoder.cc
index 7a616a038a..d89de9a550 100644
--- a/system/stack/a2dp/a2dp_vendor_ldac_encoder.cc
+++ b/system/stack/a2dp/a2dp_vendor_ldac_encoder.cc
@@ -31,7 +31,6 @@
#include "a2dp_vendor_ldac.h"
#include "common/time_util.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/properties.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/a2dp/a2dp_vendor_opus.cc b/system/stack/a2dp/a2dp_vendor_opus.cc
index f6fb3c3e2d..fac881856f 100644
--- a/system/stack/a2dp/a2dp_vendor_opus.cc
+++ b/system/stack/a2dp/a2dp_vendor_opus.cc
@@ -31,7 +31,6 @@
#include "a2dp_vendor_opus_decoder.h"
#include "a2dp_vendor_opus_encoder.h"
#include "internal_include/bt_trace.h"
-#include "os/log.h"
#include "osi/include/osi.h"
using namespace bluetooth;
diff --git a/system/stack/a2dp/a2dp_vendor_opus_decoder.cc b/system/stack/a2dp/a2dp_vendor_opus_decoder.cc
index 25658e60c0..bbbd3a2c3b 100644
--- a/system/stack/a2dp/a2dp_vendor_opus_decoder.cc
+++ b/system/stack/a2dp/a2dp_vendor_opus_decoder.cc
@@ -22,7 +22,6 @@
#include <opus.h>
#include "a2dp_vendor_opus.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
using namespace bluetooth;
diff --git a/system/stack/a2dp/a2dp_vendor_opus_encoder.cc b/system/stack/a2dp/a2dp_vendor_opus_encoder.cc
index b59288c7c6..e7476c1028 100644
--- a/system/stack/a2dp/a2dp_vendor_opus_encoder.cc
+++ b/system/stack/a2dp/a2dp_vendor_opus_encoder.cc
@@ -26,7 +26,6 @@
#include "a2dp_vendor.h"
#include "a2dp_vendor_opus.h"
#include "common/time_util.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/osi.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/acl/ble_acl.cc b/system/stack/acl/ble_acl.cc
index 1f5d5b580c..0606716f75 100644
--- a/system/stack/acl/ble_acl.cc
+++ b/system/stack/acl/ble_acl.cc
@@ -25,7 +25,7 @@
#include "stack/btm/btm_dev.h"
#include "stack/btm/btm_int_types.h"
#include "stack/btm/btm_sec.h"
-#include "stack/gatt/connection_manager.h"
+#include "stack/connection_manager/connection_manager.h"
#include "stack/include/acl_api.h"
#include "stack/include/btm_ble_addr.h"
#include "stack/include/btm_ble_privacy.h"
diff --git a/system/stack/acl/btm_acl.cc b/system/stack/acl/btm_acl.cc
index 612fd9dc63..0c52e80bb6 100644
--- a/system/stack/acl/btm_acl.cc
+++ b/system/stack/acl/btm_acl.cc
@@ -76,6 +76,7 @@
#include "stack/include/l2cap_acl_interface.h"
#include "stack/include/l2cdefs.h"
#include "stack/include/main_thread.h"
+#include "stack/l2cap/l2c_int.h"
#include "types/hci_role.h"
#include "types/raw_address.h"
@@ -96,8 +97,6 @@ using bluetooth::legacy::hci::GetInterface;
void BTM_update_version_info(const RawAddress& bd_addr,
const remote_version_info& remote_version_info);
-void l2c_link_hci_conn_comp(tHCI_STATUS status, uint16_t handle, const RawAddress& p_bda);
-
void BTM_db_reset(void);
extern tBTM_CB btm_cb;
diff --git a/system/stack/acl/btm_pm.cc b/system/stack/acl/btm_pm.cc
index f77efd47b7..c34e776a1f 100644
--- a/system/stack/acl/btm_pm.cc
+++ b/system/stack/acl/btm_pm.cc
@@ -42,7 +42,6 @@
#include "internal_include/bt_target.h"
#include "main/shim/dumpsys.h"
#include "main/shim/entry.h"
-#include "os/log.h"
#include "osi/include/stack_power_telemetry.h"
#include "stack/btm/btm_int_types.h"
#include "stack/include/bt_types.h"
diff --git a/system/stack/avct/avct_api.cc b/system/stack/avct/avct_api.cc
index 10c441d876..d4a6aab45e 100644
--- a/system/stack/avct/avct_api.cc
+++ b/system/stack/avct/avct_api.cc
@@ -28,11 +28,14 @@
#include <com_android_bluetooth_flags.h>
#include <string.h>
-#include "avct_int.h"
#include "bta/include/bta_sec_api.h"
#include "internal_include/bt_target.h"
+#include "main/shim/dumpsys.h"
#include "osi/include/allocator.h"
+#include "stack/avct/avct_int.h"
+#include "stack/include/avct_api.h"
#include "stack/include/bt_hdr.h"
+#include "stack/include/bt_psm_types.h"
#include "stack/include/l2cap_interface.h"
#include "types/raw_address.h"
@@ -68,20 +71,20 @@ void AVCT_Register() {
/* register PSM with L2CAP */
if (!stack::l2cap::get_interface().L2CA_RegisterWithSecurity(
- AVCT_PSM, avct_l2c_appl, true /* enable_snoop */, nullptr, kAvrcMtu, 0, sec)) {
- log::error("Unable to register with L2CAP AVCT profile psm:AVCT_PSM[0x0017]");
+ BT_PSM_AVCTP, avct_l2c_appl, true /* enable_snoop */, nullptr, kAvrcMtu, 0, sec)) {
+ log::error("Unable to register with L2CAP AVCT profile psm:{}", bt_psm_text(BT_PSM_AVCTP));
}
/* Include the browsing channel which uses eFCR */
- tL2CAP_ERTM_INFO ertm_info;
- ertm_info.preferred_mode = L2CAP_FCR_ERTM_MODE;
+ tL2CAP_ERTM_INFO ertm_info = {
+ .preferred_mode = L2CAP_FCR_ERTM_MODE,
+ };
if (!stack::l2cap::get_interface().L2CA_RegisterWithSecurity(
- AVCT_BR_PSM, avct_l2c_br_appl, true /*enable_snoop*/, &ertm_info, kAvrcBrMtu,
+ BT_PSM_AVCTP_BROWSE, avct_l2c_br_appl, true /*enable_snoop*/, &ertm_info, kAvrcBrMtu,
AVCT_MIN_BROWSE_MTU, sec)) {
- log::error(
- "Unable to register with L2CAP AVCT_BR profile "
- "psm:AVCT_BR_PSM[0x001b]");
+ log::error("Unable to register with L2CAP AVCT_BROWSE profile psm:{}",
+ bt_psm_text(BT_PSM_AVCTP_BROWSE));
}
}
@@ -103,10 +106,17 @@ void AVCT_Deregister(void) {
log::verbose("AVCT_Deregister");
/* deregister PSM with L2CAP */
- stack::l2cap::get_interface().L2CA_Deregister(AVCT_PSM);
+ stack::l2cap::get_interface().L2CA_Deregister(BT_PSM_AVCTP);
/* deregister AVCT_BR_PSM with L2CAP */
- stack::l2cap::get_interface().L2CA_Deregister(AVCT_BR_PSM);
+ stack::l2cap::get_interface().L2CA_Deregister(BT_PSM_AVCTP_BROWSE);
+
+ // Clean up AVCTP data structures
+ for (int i = 0; i < AVCT_NUM_LINKS; i++) {
+ osi_free(avct_cb.lcb[i].p_rx_msg);
+ fixed_queue_free(avct_cb.lcb[i].tx_q, nullptr);
+ osi_free_and_reset((void**)&(avct_cb.bcb[i].p_tx_msg));
+ }
}
/*******************************************************************************
@@ -131,7 +141,7 @@ uint16_t AVCT_CreateConn(uint8_t* p_handle, tAVCT_CC* p_cc, const RawAddress& pe
tAVCT_CCB* p_ccb;
tAVCT_LCB* p_lcb;
- log::verbose("AVCT_CreateConn: {}, control:{}", p_cc->role, p_cc->control);
+ log::verbose("AVCT_CreateConn:{}, control:0x{:x}", avct_role_text(p_cc->role), p_cc->control);
/* Allocate ccb; if no ccbs, return failure */
p_ccb = avct_ccb_alloc(p_cc);
@@ -142,7 +152,7 @@ uint16_t AVCT_CreateConn(uint8_t* p_handle, tAVCT_CC* p_cc, const RawAddress& pe
*p_handle = avct_ccb_to_idx(p_ccb);
/* if initiator connection */
- if (p_cc->role == AVCT_INT) {
+ if (p_cc->role == AVCT_ROLE_INITIATOR) {
/* find link; if none allocate a new one */
p_lcb = avct_lcb_by_bd(peer_addr);
if (p_lcb == NULL) {
@@ -162,9 +172,10 @@ uint16_t AVCT_CreateConn(uint8_t* p_handle, tAVCT_CC* p_cc, const RawAddress& pe
if (result == AVCT_SUCCESS) {
/* bind lcb to ccb */
p_ccb->p_lcb = p_lcb;
- log::verbose("ch_state: {}", p_lcb->ch_state);
- tAVCT_LCB_EVT avct_lcb_evt;
- avct_lcb_evt.p_ccb = p_ccb;
+ log::verbose("ch_state:{}", avct_ch_state_text(p_lcb->ch_state));
+ tAVCT_LCB_EVT avct_lcb_evt = {
+ .p_ccb = p_ccb,
+ };
avct_lcb_event(p_lcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt);
}
}
@@ -226,13 +237,13 @@ uint16_t AVCT_RemoveConn(uint8_t handle) {
* Returns AVCT_SUCCESS if successful, otherwise error.
*
******************************************************************************/
-uint16_t AVCT_CreateBrowse(uint8_t handle, uint8_t role) {
+uint16_t AVCT_CreateBrowse(uint8_t handle, tAVCT_ROLE role) {
uint16_t result = AVCT_SUCCESS;
tAVCT_CCB* p_ccb;
tAVCT_BCB* p_bcb;
int index;
- log::verbose("AVCT_CreateBrowse: {}", role);
+ log::verbose("AVCT_CreateBrowse: role:{}", avct_role_text(role));
/* map handle to ccb */
p_ccb = avct_ccb_by_idx(handle);
@@ -246,7 +257,7 @@ uint16_t AVCT_CreateBrowse(uint8_t handle, uint8_t role) {
}
/* if initiator connection */
- if (role == AVCT_INT) {
+ if (role == AVCT_ROLE_INITIATOR) {
/* the link control block must exist before this function is called as INT.
*/
if ((p_ccb->p_lcb == NULL) || (p_ccb->p_lcb->allocated == 0)) {
@@ -266,7 +277,7 @@ uint16_t AVCT_CreateBrowse(uint8_t handle, uint8_t role) {
/* bind bcb to ccb */
p_ccb->p_bcb = p_bcb;
p_bcb->peer_addr = p_ccb->p_lcb->peer_addr;
- log::verbose("ch_state: {}", p_bcb->ch_state);
+ log::verbose("Created BCB ch_state:{}", avct_ch_state_text(p_bcb->ch_state));
tAVCT_LCB_EVT avct_lcb_evt;
avct_lcb_evt.p_ccb = p_ccb;
avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt);
@@ -390,7 +401,7 @@ uint16_t AVCT_MsgReq(uint8_t handle, uint8_t label, uint8_t cr, BT_HDR* p_msg) {
if (p_msg == NULL) {
return AVCT_NO_RESOURCES;
}
- log::verbose("len: {} layer_specific: {}", p_msg->len, p_msg->layer_specific);
+ log::verbose("msg_len:{} msg_layer_specific:{}", p_msg->len, p_msg->layer_specific);
/* map handle to ccb */
p_ccb = avct_ccb_by_idx(handle);
@@ -432,3 +443,37 @@ uint16_t AVCT_MsgReq(uint8_t handle, uint8_t label, uint8_t cr, BT_HDR* p_msg) {
}
return result;
}
+
+#define DUMPSYS_TAG "stack::avct"
+
+void AVCT_Dumpsys(int fd) {
+ LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG);
+ for (int i = 0; i < AVCT_NUM_CONN; i++) {
+ const tAVCT_CCB& ccb = avct_cb.ccb[i];
+ if (!ccb.allocated) {
+ continue;
+ }
+ LOG_DUMPSYS(fd, " Id:%2u profile_uuid:0x%04x role:%s control:0x%2x", i, ccb.cc.pid,
+ avct_role_text(ccb.cc.role).c_str(), ccb.cc.control);
+ if (ccb.p_lcb) { // tAVCT_LCB
+ LOG_DUMPSYS(fd,
+ " Link : peer:%s lcid:0x%04x sm_state:%-24s ch_state:%s conflict_lcid:0x%04x",
+ fmt::format("{}", ccb.p_lcb->peer_addr).c_str(), ccb.p_lcb->ch_lcid,
+ avct_sm_state_text(ccb.p_lcb->state).c_str(),
+ avct_ch_state_text(ccb.p_lcb->ch_state).c_str(), ccb.p_lcb->conflict_lcid);
+ } else {
+ LOG_DUMPSYS(fd, " Link : No link channel");
+ }
+
+ if (ccb.p_bcb) { // tAVCT_BCB
+ LOG_DUMPSYS(fd,
+ " Browse: peer:%s lcid:0x%04x sm_state:%-24s ch_state:%s conflict_lcid:0x%04x",
+ fmt::format("{}", ccb.p_bcb->peer_addr).c_str(), ccb.p_bcb->ch_lcid,
+ avct_sm_state_text(ccb.p_bcb->state).c_str(),
+ avct_ch_state_text(ccb.p_bcb->ch_state).c_str(), ccb.p_bcb->conflict_lcid);
+ } else {
+ LOG_DUMPSYS(fd, " Browse: No browse channel");
+ }
+ }
+}
+#undef DUMPSYS_TAG
diff --git a/system/stack/avct/avct_bcb_act.cc b/system/stack/avct/avct_bcb_act.cc
index 75d54bbcee..37a5d20a97 100644
--- a/system/stack/avct/avct_bcb_act.cc
+++ b/system/stack/avct/avct_bcb_act.cc
@@ -25,26 +25,41 @@
*
*****************************************************************************/
-#define LOG_TAG "bluetooth"
-
#include <bluetooth/log.h>
#include <com_android_bluetooth_flags.h>
#include <string.h>
-#include "avct_api.h"
-#include "avct_int.h"
#include "bta/include/bta_sec_api.h"
#include "btif/include/btif_av.h"
#include "internal_include/bt_target.h"
#include "osi/include/allocator.h"
-#include "osi/include/osi.h"
#include "stack/avct/avct_defs.h"
+#include "stack/avct/avct_int.h"
+#include "stack/include/avct_api.h"
#include "stack/include/bt_hdr.h"
+#include "stack/include/bt_psm_types.h"
#include "stack/include/bt_types.h"
#include "stack/include/l2cap_interface.h"
using namespace bluetooth;
+static void avct_bcb_chnl_open(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_chnl_disc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_send_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_open_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_open_fail(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_close_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_close_cfm(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_cong_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_bind_conn(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_bind_fail(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_unbind_disc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_chk_disc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_discard_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_dealloc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+static void avct_bcb_free_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
+
/* action function list */
const tAVCT_BCB_ACTION avct_bcb_action[] = {
avct_bcb_chnl_open, /* AVCT_LCB_CHNL_OPEN */
@@ -92,7 +107,7 @@ static BT_HDR* avct_bcb_msg_asmbl(tAVCT_BCB* /* p_bcb */, BT_HDR* p_buf) {
/* must be single packet - can not fragment */
if (pkt_type != AVCT_PKT_TYPE_SINGLE) {
osi_free_and_reset((void**)&p_buf);
- log::warn("Pkt type={} - fragmentation not allowed. drop it", pkt_type);
+ log::warn("Pkt type:{} - fragmentation not allowed. drop it", pkt_type);
}
return p_buf;
}
@@ -110,19 +125,15 @@ static BT_HDR* avct_bcb_msg_asmbl(tAVCT_BCB* /* p_bcb */, BT_HDR* p_buf) {
void avct_bcb_chnl_open(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* /* p_data */) {
uint16_t result = AVCT_RESULT_FAIL;
tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
- tL2CAP_ERTM_INFO ertm_info;
-
- /* Set the FCR options: Browsing channel mandates ERTM */
- ertm_info.preferred_mode = L2CAP_FCR_ERTM_MODE;
/* call l2cap connect req */
p_bcb->ch_state = AVCT_CH_CONN;
if (com::android::bluetooth::flags::use_encrypt_req_for_av()) {
p_bcb->ch_lcid = stack::l2cap::get_interface().L2CA_ConnectReqWithSecurity(
- AVCT_BR_PSM, p_lcb->peer_addr, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
+ BT_PSM_AVCTP_BROWSE, p_lcb->peer_addr, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
} else {
p_bcb->ch_lcid = stack::l2cap::get_interface().L2CA_ConnectReqWithSecurity(
- AVCT_BR_PSM, p_lcb->peer_addr, BTA_SEC_AUTHENTICATE);
+ BT_PSM_AVCTP_BROWSE, p_lcb->peer_addr, BTA_SEC_AUTHENTICATE);
}
if (p_bcb->ch_lcid == 0) {
/* if connect req failed, send ourselves close event */
@@ -162,56 +173,68 @@ void avct_bcb_unbind_disc(tAVCT_BCB* /* p_bcb */, tAVCT_LCB_EVT* p_data) {
* Returns Nothing.
*
******************************************************************************/
+namespace {
+bool is_valid_role_check(const tAVCT_CCB* p_ccb) {
+ return com::android::bluetooth::flags::
+ associate_browse_l2cap_request_with_active_control_channel()
+ ? true
+ : p_ccb->cc.role == AVCT_ROLE_ACCEPTOR;
+}
+} // namespace
+
void avct_bcb_open_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
- tAVCT_CCB* p_ccb_bind = NULL;
- bool bind = false;
- tAVCT_UL_MSG ul_msg;
+ tAVCT_CCB* p_ccb_bind = nullptr;
for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
- /* if ccb allocated and */
- if (p_ccb->allocated) {
- /* if bound to this bcb send connect confirm event */
- if (p_ccb->p_bcb == p_bcb) {
- bind = true;
- p_ccb_bind = p_ccb;
- p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_BROWSE_CONN_CFM_EVT, 0,
- &p_ccb->p_lcb->peer_addr);
- }
+ if (!p_ccb->allocated) {
+ continue;
+ }
+
+ /* if ccb allocated and bound to this bcb send connect confirm event */
+ if (p_ccb->p_bcb == p_bcb) {
+ p_ccb_bind = p_ccb;
+ p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_BROWSE_CONN_CFM_EVT, 0,
+ &p_ccb->p_lcb->peer_addr);
+ } else if ((p_ccb->p_bcb == NULL) && is_valid_role_check(p_ccb) && (p_ccb->p_lcb != NULL) &&
+ p_bcb->peer_addr == p_ccb->p_lcb->peer_addr) {
/* if unbound acceptor and lcb allocated and bd_addr are the same for bcb
and lcb */
- else if ((p_ccb->p_bcb == NULL) && (p_ccb->cc.role == AVCT_ACP) && (p_ccb->p_lcb != NULL) &&
- p_bcb->peer_addr == p_ccb->p_lcb->peer_addr) {
- /* bind bcb to ccb and send connect ind event */
- bind = true;
- p_ccb_bind = p_ccb;
- p_ccb->p_bcb = p_bcb;
- p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_BROWSE_CONN_IND_EVT, 0,
- &p_ccb->p_lcb->peer_addr);
- }
+ /* bind bcb to ccb and send connect ind event */
+ p_ccb_bind = p_ccb;
+ p_ccb->p_bcb = p_bcb;
+ p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_BROWSE_CONN_IND_EVT, 0,
+ &p_ccb->p_lcb->peer_addr);
}
}
/* if no ccbs bound to this lcb, disconnect */
- if (!bind) {
+ if (p_ccb_bind == nullptr) {
+ log::warn("Ignoring incoming browse request and closing channel from peer:{} lcid:0x{:04x}",
+ p_bcb->peer_addr, p_bcb->ch_lcid);
avct_bcb_event(p_bcb, AVCT_LCB_INT_CLOSE_EVT, p_data);
return;
}
- if (!p_bcb->p_tx_msg || !p_ccb_bind) {
+ if (!p_bcb->p_tx_msg) {
+ log::warn("Received browse packet with no browse data peer:{} lcid:0x{:04x}", p_bcb->peer_addr,
+ p_bcb->ch_lcid);
return;
}
- ul_msg.p_buf = p_bcb->p_tx_msg;
- ul_msg.p_ccb = p_ccb_bind;
- ul_msg.label = (uint8_t)(p_bcb->p_tx_msg->layer_specific & 0xFF);
- ul_msg.cr = (uint8_t)((p_bcb->p_tx_msg->layer_specific & 0xFF00) >> 8);
+ tAVCT_UL_MSG ul_msg = {
+ .p_buf = p_bcb->p_tx_msg,
+ .p_ccb = p_ccb_bind,
+ .label = (uint8_t)(p_bcb->p_tx_msg->layer_specific & 0xFF),
+ .cr = (uint8_t)((p_bcb->p_tx_msg->layer_specific & 0xFF00) >> 8),
+ };
p_bcb->p_tx_msg->layer_specific = AVCT_DATA_BROWSE;
p_bcb->p_tx_msg = NULL;
/* send msg event to bcb */
- tAVCT_LCB_EVT avct_lcb_evt;
- avct_lcb_evt.ul_msg = ul_msg;
+ tAVCT_LCB_EVT avct_lcb_evt = {
+ .ul_msg = ul_msg,
+ };
avct_bcb_event(p_bcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
}
@@ -253,7 +276,7 @@ void avct_bcb_close_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* /* p_data */) {
for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
- if (p_ccb->cc.role == AVCT_INT) {
+ if (p_ccb->cc.role == AVCT_ROLE_INITIATOR) {
(*p_ccb->cc.p_ctrl_cback)(avct_ccb_to_idx(p_ccb), AVCT_BROWSE_DISCONN_CFM_EVT, 0,
&p_lcb->peer_addr);
} else {
@@ -277,26 +300,19 @@ void avct_bcb_close_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* /* p_data */) {
*
******************************************************************************/
void avct_bcb_close_cfm(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
- tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
- uint8_t event = 0;
/* Whether BCB initiated channel close */
- bool ch_close = p_bcb->ch_close;
- tAVCT_CTRL_CBACK* p_cback;
-
+ const bool ch_close = p_bcb->ch_close;
p_bcb->ch_close = false;
p_bcb->allocated = 0;
+
+ tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
if (p_ccb->allocated && (p_ccb->p_bcb == p_bcb)) {
/* if this ccb initiated close send disconnect cfm otherwise ind */
- if (ch_close) {
- event = AVCT_BROWSE_DISCONN_CFM_EVT;
- } else {
- event = AVCT_BROWSE_DISCONN_IND_EVT;
- }
-
- p_cback = p_ccb->cc.p_ctrl_cback;
- p_ccb->p_bcb = NULL;
- if (p_ccb->p_lcb == NULL) {
+ uint8_t event = ch_close ? AVCT_BROWSE_DISCONN_CFM_EVT : AVCT_BROWSE_DISCONN_IND_EVT;
+ tAVCT_CTRL_CBACK* p_cback = p_ccb->cc.p_ctrl_cback;
+ p_ccb->p_bcb = nullptr;
+ if (p_ccb->p_lcb == nullptr) {
avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
}
(*p_cback)(avct_ccb_to_idx(p_ccb), event, p_data->result, &p_bcb->peer_addr);
@@ -386,11 +402,10 @@ void avct_bcb_bind_fail(tAVCT_BCB* /* p_bcb */, tAVCT_LCB_EVT* p_data) {
******************************************************************************/
void avct_bcb_cong_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
- uint8_t event;
tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
/* set event */
- event = (p_data->cong) ? AVCT_BROWSE_CONG_IND_EVT : AVCT_BROWSE_UNCONG_IND_EVT;
+ uint8_t event = (p_data->cong) ? AVCT_BROWSE_CONG_IND_EVT : AVCT_BROWSE_UNCONG_IND_EVT;
/* send event to all ccbs on this lcb */
for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
@@ -424,7 +439,8 @@ void avct_bcb_discard_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
p_bcb->p_tx_msg->layer_specific = (p_data->ul_msg.cr << 8) + p_data->ul_msg.label;
/* the channel is closed, opening or closing - open it again */
- log::verbose("ch_state: {}, allocated:{}->{}", p_bcb->ch_state, p_bcb->allocated,
+ log::verbose("ch_state:{} bcb_allocated:{} ccb_lcb_allocated:{}",
+ avct_ch_state_text(p_bcb->ch_state), p_bcb->allocated,
p_data->ul_msg.p_ccb->p_lcb->allocated);
p_bcb->allocated = p_data->ul_msg.p_ccb->p_lcb->allocated;
avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT, (tAVCT_LCB_EVT*)p_data->ul_msg.p_ccb);
@@ -453,7 +469,7 @@ void avct_bcb_send_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
/* initialize packet type and other stuff */
if (curr_msg_len > (p_bcb->peer_mtu - AVCT_HDR_LEN_SINGLE)) {
- log::error("msg len ({}) exceeds peer mtu({}-{})!!", curr_msg_len, p_bcb->peer_mtu,
+ log::error("msg_len:{} exceeds peer mtu:{} header-{})!!", curr_msg_len, p_bcb->peer_mtu,
AVCT_HDR_LEN_SINGLE);
osi_free_and_reset((void**)&p_data->ul_msg.p_buf);
return;
@@ -477,7 +493,7 @@ void avct_bcb_send_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
/* send message to L2CAP */
if (stack::l2cap::get_interface().L2CA_DataWrite(p_bcb->ch_lcid, p_buf) !=
tL2CAP_DW_RESULT::SUCCESS) {
- log::warn("Unable to write L2CAP data peer:{} cid:{}", p_bcb->peer_addr, p_bcb->ch_lcid);
+ log::warn("Unable to write L2CAP data peer:{} cid:0x{:04x}", p_bcb->peer_addr, p_bcb->ch_lcid);
}
}
@@ -532,7 +548,7 @@ void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
}
if (p_data->p_buf->len < AVCT_HDR_LEN_SINGLE) {
- log::warn("Invalid AVCTP packet length {}: must be at least {}", p_data->p_buf->len,
+ log::warn("Invalid AVCTP packet length:{} must be at least:{}", p_data->p_buf->len,
AVCT_HDR_LEN_SINGLE);
osi_free_and_reset((void**)&p_data->p_buf);
return;
@@ -547,7 +563,7 @@ void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
/* check for invalid cr_ipid */
if (cr_ipid == AVCT_CR_IPID_INVALID) {
- log::warn("Invalid cr_ipid {}", cr_ipid);
+ log::warn("Invalid cr_ipid:{}", cr_ipid);
osi_free_and_reset((void**)&p_data->p_buf);
return;
}
@@ -572,7 +588,7 @@ void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
}
/* PID not found; drop message */
- log::warn("No ccb for PID={:x}", pid);
+ log::warn("No ccb for PID=0x{:x}", pid);
osi_free_and_reset((void**)&p_data->p_buf);
/* if command send reject */
@@ -586,7 +602,8 @@ void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
p_buf->layer_specific = AVCT_DATA_BROWSE;
if (stack::l2cap::get_interface().L2CA_DataWrite(p_bcb->ch_lcid, p_buf) !=
tL2CAP_DW_RESULT::SUCCESS) {
- log::warn("Unable to write L2CAP data peer:{} cid:{}", p_bcb->peer_addr, p_bcb->ch_lcid);
+ log::warn("Unable to write L2CAP data peer:{} cid:0x{:04x}", p_bcb->peer_addr,
+ p_bcb->ch_lcid);
}
}
}
@@ -604,13 +621,13 @@ void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) {
void avct_bcb_dealloc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* /* p_data */) {
tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
- log::verbose("{}", p_bcb->allocated);
+ log::verbose("BCB allocated:{}", p_bcb->allocated);
for (int idx = 0; idx < AVCT_NUM_CONN; idx++, p_ccb++) {
/* if ccb allocated and */
if ((p_ccb->allocated) && (p_ccb->p_bcb == p_bcb)) {
p_ccb->p_bcb = NULL;
- log::verbose("used by ccb: {}", idx);
+ log::verbose("used by ccb idx:{}", idx);
break;
}
}
@@ -705,6 +722,6 @@ tAVCT_BCB* avct_bcb_by_lcid(uint16_t lcid) {
}
/* out of lcbs */
- log::warn("No bcb for lcid {:x}", lcid);
- return NULL;
+ log::warn("No bcb for lcid 0x{:04x}", lcid);
+ return nullptr;
}
diff --git a/system/stack/avct/avct_ccb.cc b/system/stack/avct/avct_ccb.cc
index 6210fd2fa7..6ffa34c3fb 100644
--- a/system/stack/avct/avct_ccb.cc
+++ b/system/stack/avct/avct_ccb.cc
@@ -23,8 +23,6 @@
*
******************************************************************************/
-#define LOG_TAG "avctp"
-
#include <bluetooth/log.h>
#include <string.h>
@@ -53,7 +51,7 @@ tAVCT_CCB* avct_ccb_alloc(tAVCT_CC* p_cc) {
if (!p_ccb->allocated) {
p_ccb->allocated = AVCT_ALOC_LCB;
memcpy(&p_ccb->cc, p_cc, sizeof(tAVCT_CC));
- log::verbose("avct_ccb_alloc {}", i);
+ log::verbose("Allocated ccb idx:{}", i);
break;
}
}
@@ -80,7 +78,7 @@ tAVCT_CCB* avct_ccb_alloc(tAVCT_CC* p_cc) {
void avct_ccb_dealloc(tAVCT_CCB* p_ccb, uint8_t event, uint16_t result, const RawAddress* bd_addr) {
tAVCT_CTRL_CBACK* p_cback = p_ccb->cc.p_ctrl_cback;
- log::verbose("avct_ccb_dealloc {}", avct_ccb_to_idx(p_ccb));
+ log::verbose("Deallocating idx:{}", avct_ccb_to_idx(p_ccb));
if (p_ccb->p_bcb == NULL) {
memset(p_ccb, 0, sizeof(tAVCT_CCB));
@@ -131,11 +129,11 @@ tAVCT_CCB* avct_ccb_by_idx(uint8_t idx) {
/* verify ccb is allocated */
if (!p_ccb->allocated) {
p_ccb = NULL;
- log::warn("ccb {} not allocated", idx);
+ log::warn("ccb idx:{} not allocated", idx);
}
} else {
p_ccb = NULL;
- log::warn("No ccb for idx {}", idx);
+ log::warn("No ccb for idx:{}", idx);
}
return p_ccb;
}
diff --git a/system/stack/avct/avct_int.h b/system/stack/avct/avct_int.h
index 0800523062..9efe7ad25e 100644
--- a/system/stack/avct/avct_int.h
+++ b/system/stack/avct/avct_int.h
@@ -24,7 +24,10 @@
#ifndef AVCT_INT_H
#define AVCT_INT_H
+#include <string>
+
#include "avct_api.h"
+#include "include/macros.h"
#include "internal_include/bt_target.h"
#include "osi/include/fixed_queue.h"
#include "stack/include/bt_hdr.h"
@@ -48,10 +51,22 @@ enum {
};
/* "states" used for L2CAP channel */
-#define AVCT_CH_IDLE 0 /* No connection */
-#define AVCT_CH_CONN 1 /* Waiting for connection confirm */
-#define AVCT_CH_CFG 2 /* Waiting for configuration complete */
-#define AVCT_CH_OPEN 3 /* Channel opened */
+enum tAVCT_CH {
+ AVCT_CH_IDLE = 0, /* No connection */
+ AVCT_CH_CONN = 1, /* Waiting for connection confirm */
+ AVCT_CH_CFG = 2, /* Waiting for configuration complete */
+ AVCT_CH_OPEN = 3, /* Channel opened */
+};
+
+inline std::string avct_ch_state_text(const int& state) {
+ switch (state) {
+ CASE_RETURN_STRING(AVCT_CH_IDLE);
+ CASE_RETURN_STRING(AVCT_CH_CONN);
+ CASE_RETURN_STRING(AVCT_CH_CFG);
+ CASE_RETURN_STRING(AVCT_CH_OPEN);
+ }
+ RETURN_UNKNOWN_TYPE_STRING(int, state);
+}
/* "no event" indicator used by ccb dealloc */
#define AVCT_NO_EVT 0xFF
@@ -59,16 +74,6 @@ enum {
/*****************************************************************************
* data types
****************************************************************************/
-/* sub control block type - common data members for tAVCT_LCB and tAVCT_BCB */
-typedef struct {
- uint16_t peer_mtu; /* peer l2c mtu */
- uint16_t ch_result; /* L2CAP connection result value */
- uint16_t ch_lcid; /* L2CAP channel LCID */
- uint8_t allocated; /* 0, not allocated. index+1, otherwise. */
- uint8_t state; /* The state machine state */
- uint8_t ch_state; /* L2CAP channel state */
-} tAVCT_SCB;
-
/* link control block type */
typedef struct {
uint16_t peer_mtu; /* peer l2c mtu */
@@ -89,7 +94,7 @@ typedef struct {
uint16_t peer_mtu; /* peer l2c mtu */
uint16_t ch_result; /* L2CAP connection result value */
uint16_t ch_lcid; /* L2CAP channel LCID */
- uint8_t allocated; /* 0, not allocated. index+1, otherwise. */
+ uint8_t allocated; // 0: no link allocated. otherwise link index+1
uint8_t state; /* The state machine state */
uint8_t ch_state; /* L2CAP channel state */
uint16_t conflict_lcid; /* L2CAP channel LCID */
@@ -173,23 +178,6 @@ void avct_lcb_free_msg_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data);
/* BCB action functions */
typedef void (*tAVCT_BCB_ACTION)(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_chnl_open(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_unbind_disc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_open_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_open_fail(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_close_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_close_cfm(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_bind_conn(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_chk_disc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_chnl_disc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_bind_fail(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_cong_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_discard_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_send_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-void avct_bcb_free_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
-
-void avct_bcb_dealloc(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data);
extern const tAVCT_BCB_ACTION avct_bcb_action[];
extern const uint8_t avct_lcb_pkt_type_len[];
@@ -203,6 +191,8 @@ tAVCT_CCB* avct_ccb_by_idx(uint8_t idx);
extern bool avct_msg_ind_for_src_sink_coexist(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data,
uint8_t label, uint8_t cr_ipid, uint16_t pid);
+std::string avct_sm_state_text(const int& state);
+
/*****************************************************************************
* global data
****************************************************************************/
diff --git a/system/stack/avct/avct_l2c.cc b/system/stack/avct/avct_l2c.cc
index adca67c851..e3001eeaa2 100644
--- a/system/stack/avct/avct_l2c.cc
+++ b/system/stack/avct/avct_l2c.cc
@@ -21,8 +21,6 @@
* This AVCTP module interfaces to L2CAP
*
******************************************************************************/
-#define LOG_TAG "avctp"
-
#include <bluetooth/log.h>
#include "avct_api.h"
@@ -32,18 +30,20 @@
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/l2cap_interface.h"
+#include "stack/include/l2cdefs.h"
#include "types/raw_address.h"
using namespace bluetooth;
/* callback function declarations */
-void avct_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, uint16_t psm, uint8_t id);
-void avct_l2c_connect_cfm_cback(uint16_t lcid, tL2CAP_CONN result);
-void avct_l2c_config_cfm_cback(uint16_t lcid, uint16_t result, tL2CAP_CFG_INFO* p_cfg);
-void avct_l2c_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
-void avct_l2c_disconnect_ind_cback(uint16_t lcid, bool ack_needed);
-void avct_l2c_congestion_ind_cback(uint16_t lcid, bool is_congested);
-void avct_l2c_data_ind_cback(uint16_t lcid, BT_HDR* p_buf);
+static void avct_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, uint16_t psm,
+ uint8_t id);
+static void avct_l2c_connect_cfm_cback(uint16_t lcid, tL2CAP_CONN result);
+static void avct_l2c_config_cfm_cback(uint16_t lcid, uint16_t result, tL2CAP_CFG_INFO* p_cfg);
+static void avct_l2c_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
+static void avct_l2c_disconnect_ind_cback(uint16_t lcid, bool ack_needed);
+static void avct_l2c_congestion_ind_cback(uint16_t lcid, bool is_congested);
+static void avct_l2c_data_ind_cback(uint16_t lcid, BT_HDR* p_buf);
static void avct_on_l2cap_error(uint16_t lcid, uint16_t result);
/* L2CAP callback function structure */
@@ -103,21 +103,19 @@ static bool avct_l2c_is_passive(tAVCT_LCB* p_lcb) {
******************************************************************************/
void avct_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, uint16_t /* psm */,
uint8_t /* id */) {
- tAVCT_LCB* p_lcb;
tL2CAP_CONN result = tL2CAP_CONN::L2CAP_CONN_OK;
/* do we already have a channel for this peer? */
- p_lcb = avct_lcb_by_bd(bd_addr);
- if (p_lcb == NULL) {
+ tAVCT_LCB* p_lcb = avct_lcb_by_bd(bd_addr);
+ if (p_lcb == nullptr) {
/* no, allocate lcb */
p_lcb = avct_lcb_alloc(bd_addr);
- if (p_lcb == NULL) {
+ if (p_lcb == nullptr) {
/* no ccb available, reject L2CAP connection */
result = tL2CAP_CONN::L2CAP_CONN_NO_RESOURCES;
}
- }
- /* else we already have a channel for this peer */
- else {
+ } else {
+ /* else we already have a channel for this peer */
if (!avct_l2c_is_passive(p_lcb) || (p_lcb->ch_state == AVCT_CH_OPEN)) {
/* this LCB included CT role - reject */
result = tL2CAP_CONN::L2CAP_CONN_NO_RESOURCES;
@@ -125,19 +123,8 @@ void avct_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, uint16
/* TG role only - accept the connection from CT. move the channel ID to
* the conflict list */
p_lcb->conflict_lcid = p_lcb->ch_lcid;
- log::verbose("avct_l2c_connect_ind_cback conflict_lcid:0x{:x}", p_lcb->conflict_lcid);
- }
- }
-
- if (p_lcb) {
- log::verbose("avct_l2c_connect_ind_cback: 0x{:x}, res: {}, ch_state: {}", lcid, result,
- p_lcb->ch_state);
- }
-
- /* If we reject the connection, send DisconnectReq */
- if (result != tL2CAP_CONN::L2CAP_CONN_OK) {
- if (!stack::l2cap::get_interface().L2CA_DisconnectReq(lcid)) {
- log::warn("Unable to send L2CAP disconnect request peer:{} cid:{}", bd_addr, lcid);
+ log::verbose("Accept connection from controller lcid:0x{:04x} conflict_lcid:0x{:04x}", lcid,
+ p_lcb->conflict_lcid);
}
}
@@ -146,10 +133,13 @@ void avct_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, uint16
if (btif_av_src_sink_coexist_enabled()) {
tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
for (int i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
- if (p_ccb && p_ccb->allocated && (p_ccb->p_lcb == NULL) && (p_ccb->cc.role == AVCT_ACP)) {
+ if (p_ccb && p_ccb->allocated && (p_ccb->p_lcb == NULL) &&
+ (p_ccb->cc.role == AVCT_ROLE_ACCEPTOR)) {
p_ccb->p_lcb = p_lcb;
- log::verbose("ACP bind {} ccb to lcb, alloc {}, lcb {}, role {}, pid 0x{:x}", i,
- p_ccb->allocated, fmt::ptr(p_ccb->p_lcb), p_ccb->cc.role, p_ccb->cc.pid);
+ log::verbose(
+ "Source and sink coexistance enabled acceptor bind ccb to lcb idx:{} "
+ "allocated:{} role {} pid 0x{:x}",
+ i, p_ccb->allocated, avct_role_text(p_ccb->cc.role), p_ccb->cc.pid);
}
}
}
@@ -158,10 +148,18 @@ void avct_l2c_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, uint16
/* transition to configuration state */
p_lcb->ch_state = AVCT_CH_CFG;
- }
- if (p_lcb) {
- log::verbose("ch_state cni: {}", p_lcb->ch_state);
+ log::debug("Received remote connection request peer:{} lcid:0x{:04x} ch_state:{}", bd_addr,
+ lcid, avct_ch_state_text(p_lcb->ch_state));
+ } else {
+ /* If we reject the connection, send DisconnectReq */
+ if (!stack::l2cap::get_interface().L2CA_DisconnectReq(lcid)) {
+ log::warn("Unable to send L2CAP disconnect request peer:{} lcid:0x{:04x}", bd_addr, lcid);
+ }
+ log::info(
+ "Ignoring remote connection request no link or no resources peer:{} lcid:0x{:04x} "
+ "lcb_exists:{}",
+ bd_addr, lcid, p_lcb != nullptr);
}
}
@@ -186,7 +184,8 @@ static void avct_on_l2cap_error(uint16_t lcid, uint16_t result) {
/* Send L2CAP disconnect req */
if (!stack::l2cap::get_interface().L2CA_DisconnectReq(lcid)) {
- log::warn("Unable to send L2CAP disconnect request peer:{} cid:{}", p_lcb->peer_addr, lcid);
+ log::warn("Unable to send L2CAP disconnect request peer:{} lcid:0x{:04x}", p_lcb->peer_addr,
+ lcid);
}
}
}
@@ -207,36 +206,34 @@ void avct_l2c_connect_cfm_cback(uint16_t lcid, tL2CAP_CONN result) {
/* look up lcb for this channel */
p_lcb = avct_lcb_by_lcid(lcid);
if (p_lcb != NULL) {
- log::verbose(
- "avct_l2c_connect_cfm_cback lcid:0x{:x} result: {} ch_state: {}, "
- "conflict_lcid:0x{:x}",
- lcid, result, p_lcb->ch_state, p_lcb->conflict_lcid);
+ log::verbose("lcid:0x{:04x} result:{} ch_state:{} conflict_lcid:0x{:04x}", lcid, result,
+ avct_ch_state_text(p_lcb->ch_state), p_lcb->conflict_lcid);
/* if in correct state */
if (p_lcb->ch_state == AVCT_CH_CONN) {
/* if result successful */
if (result == tL2CAP_CONN::L2CAP_CONN_OK) {
/* set channel state */
p_lcb->ch_state = AVCT_CH_CFG;
- }
- /* else failure */
- else {
- log::error("invoked with non OK status");
+ } else {
+ /* else failure */
+ log::error("invoked with non OK status lcid:0x{:04x} result:{}", lcid,
+ l2cap_result_code_text(result));
}
} else if (p_lcb->conflict_lcid == lcid) {
/* we must be in AVCT_CH_CFG state for the ch_lcid channel */
- log::verbose("avct_l2c_connect_cfm_cback ch_state: {}, conflict_lcid:0x{:x}", p_lcb->ch_state,
+ log::verbose("ch_state:{} conflict_lcid:0x{:04x}", avct_ch_state_text(p_lcb->ch_state),
p_lcb->conflict_lcid);
if (result == tL2CAP_CONN::L2CAP_CONN_OK) {
/* just in case the peer also accepts our connection - Send L2CAP
* disconnect req */
if (!stack::l2cap::get_interface().L2CA_DisconnectReq(lcid)) {
- log::warn("Unable to send L2CAP disconnect request peer:{} cid:{}", p_lcb->peer_addr,
- lcid);
+ log::warn("Unable to send L2CAP disconnect request peer:{} cid:0x{:04x}",
+ p_lcb->peer_addr, lcid);
}
}
p_lcb->conflict_lcid = 0;
}
- log::verbose("ch_state cnc: {}", p_lcb->ch_state);
+ log::verbose("ch_state:{}", avct_ch_state_text(p_lcb->ch_state));
}
}
@@ -250,22 +247,29 @@ void avct_l2c_connect_cfm_cback(uint16_t lcid, tL2CAP_CONN result) {
* Returns void
*
******************************************************************************/
-void avct_l2c_config_cfm_cback(uint16_t lcid, uint16_t /* initiator */, tL2CAP_CFG_INFO* p_cfg) {
+void avct_l2c_config_cfm_cback(uint16_t lcid, uint16_t is_initiator_local, tL2CAP_CFG_INFO* p_cfg) {
avct_l2c_config_ind_cback(lcid, p_cfg);
- tAVCT_LCB* p_lcb;
-
/* look up lcb for this channel */
- p_lcb = avct_lcb_by_lcid(lcid);
- if (p_lcb != NULL) {
- log::verbose("avct_l2c_config_cfm_cback: 0x{:x}, ch_state: {},", lcid, p_lcb->ch_state);
- /* if in correct state */
- if (p_lcb->ch_state == AVCT_CH_CFG) {
- p_lcb->ch_state = AVCT_CH_OPEN;
- avct_lcb_event(p_lcb, AVCT_LCB_LL_OPEN_EVT, NULL);
- }
- log::verbose("ch_state cfc: {}", p_lcb->ch_state);
+ tAVCT_LCB* p_lcb = avct_lcb_by_lcid(lcid);
+ if (p_lcb == nullptr) {
+ log::warn("Received config confirm for unknown peer lcid::0x{:04x} is_initiator_local:{}", lcid,
+ is_initiator_local);
+ return;
+ }
+
+ /* if in correct state */
+ if (p_lcb->ch_state == AVCT_CH_CFG) {
+ p_lcb->ch_state = AVCT_CH_OPEN;
+ avct_lcb_event(p_lcb, AVCT_LCB_LL_OPEN_EVT, NULL);
+ } else {
+ log::warn(
+ "Received config confirm in wrong state lcid:0x{:04x} ch_state:{} "
+ "is_initiator_local:{}",
+ lcid, avct_ch_state_text(p_lcb->ch_state), is_initiator_local);
}
+ log::verbose("ch_state lcid:0x{:04x} ch_state:{} is_initiator_local:{}", lcid,
+ avct_ch_state_text(p_lcb->ch_state), is_initiator_local);
}
/*******************************************************************************
@@ -284,7 +288,8 @@ void avct_l2c_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) {
/* look up lcb for this channel */
p_lcb = avct_lcb_by_lcid(lcid);
if (p_lcb != NULL) {
- log::verbose("avct_l2c_config_ind_cback: 0x{:x}, ch_state: {}", lcid, p_lcb->ch_state);
+ log::verbose("avct_l2c_config_ind_cback: 0x{:04x}, ch_state:{}", lcid,
+ avct_ch_state_text(p_lcb->ch_state));
/* store the mtu in tbl */
if (p_cfg->mtu_present) {
p_lcb->peer_mtu = p_cfg->mtu;
@@ -339,7 +344,7 @@ void avct_l2c_disconnect(uint16_t lcid, uint16_t result) {
tAVCT_LCB_EVT avct_lcb_evt;
avct_lcb_evt.result = res;
avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
- log::verbose("ch_state dc: {}", p_lcb->ch_state);
+ log::verbose("ch_state:{}", p_lcb->ch_state);
}
}
@@ -377,15 +382,13 @@ void avct_l2c_congestion_ind_cback(uint16_t lcid, bool is_congested) {
*
******************************************************************************/
void avct_l2c_data_ind_cback(uint16_t lcid, BT_HDR* p_buf) {
- tAVCT_LCB* p_lcb;
-
- log::verbose("avct_l2c_data_ind_cback: 0x{:x}", lcid);
+ log::verbose("lcid: 0x{:02x}", lcid);
/* look up lcb for this channel */
- p_lcb = avct_lcb_by_lcid(lcid);
+ tAVCT_LCB* p_lcb = avct_lcb_by_lcid(lcid);
if (p_lcb != NULL) {
avct_lcb_event(p_lcb, AVCT_LCB_LL_MSG_EVT, (tAVCT_LCB_EVT*)&p_buf);
- } else /* prevent buffer leak */
- {
+ } else {
+ /* prevent buffer leak */
log::warn("ERROR -> avct_l2c_data_ind_cback drop buffer");
osi_free(p_buf);
}
diff --git a/system/stack/avct/avct_l2c_br.cc b/system/stack/avct/avct_l2c_br.cc
index 4c5ccc503b..3f76e0b76f 100644
--- a/system/stack/avct/avct_l2c_br.cc
+++ b/system/stack/avct/avct_l2c_br.cc
@@ -24,30 +24,29 @@
*
*****************************************************************************/
-#define LOG_TAG "avctp"
-
#include <bluetooth/log.h>
-#include "avct_api.h"
-#include "avct_int.h"
#include "internal_include/bt_target.h"
#include "osi/include/allocator.h"
+#include "stack/avct/avct_int.h"
+#include "stack/include/avct_api.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/l2cap_interface.h"
+#include "stack/include/l2cdefs.h"
#include "types/raw_address.h"
using namespace bluetooth;
/* callback function declarations */
-void avct_l2c_br_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, uint16_t psm,
- uint8_t id);
-void avct_l2c_br_connect_cfm_cback(uint16_t lcid, tL2CAP_CONN result);
-void avct_l2c_br_config_cfm_cback(uint16_t lcid, uint16_t result, tL2CAP_CFG_INFO* p_cfg);
-void avct_l2c_br_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
-void avct_l2c_br_disconnect_ind_cback(uint16_t lcid, bool ack_needed);
-void avct_l2c_br_congestion_ind_cback(uint16_t lcid, bool is_congested);
-void avct_l2c_br_data_ind_cback(uint16_t lcid, BT_HDR* p_buf);
-void avct_br_on_l2cap_error(uint16_t lcid, uint16_t result);
+static void avct_l2c_br_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, uint16_t psm,
+ uint8_t id);
+static void avct_l2c_br_connect_cfm_cback(uint16_t lcid, tL2CAP_CONN result);
+static void avct_l2c_br_config_cfm_cback(uint16_t lcid, uint16_t result, tL2CAP_CFG_INFO* p_cfg);
+static void avct_l2c_br_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg);
+static void avct_l2c_br_disconnect_ind_cback(uint16_t lcid, bool ack_needed);
+static void avct_l2c_br_congestion_ind_cback(uint16_t lcid, bool is_congested);
+static void avct_l2c_br_data_ind_cback(uint16_t lcid, BT_HDR* p_buf);
+static void avct_br_on_l2cap_error(uint16_t lcid, uint16_t result);
/* L2CAP callback function structure */
const tL2CAP_APPL_INFO avct_l2c_br_appl = {avct_l2c_br_connect_ind_cback,
@@ -77,9 +76,8 @@ const tL2CAP_APPL_INFO avct_l2c_br_appl = {avct_l2c_br_connect_ind_cback,
******************************************************************************/
static bool avct_l2c_br_is_passive(tAVCT_BCB* p_bcb) {
bool is_passive = false;
- tAVCT_LCB* p_lcb;
tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
- p_lcb = avct_lcb_by_bcb(p_bcb);
+ tAVCT_LCB* p_lcb = avct_lcb_by_bcb(p_bcb);
int i;
for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
@@ -106,12 +104,10 @@ static bool avct_l2c_br_is_passive(tAVCT_BCB* p_bcb) {
******************************************************************************/
void avct_l2c_br_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, uint16_t /* psm */,
uint8_t /* id */) {
- tAVCT_LCB* p_lcb;
tL2CAP_CONN result = tL2CAP_CONN::L2CAP_CONN_NO_RESOURCES;
- tAVCT_BCB* p_bcb;
- tL2CAP_ERTM_INFO ertm_info;
+ tAVCT_BCB* p_bcb{nullptr};
- p_lcb = avct_lcb_by_bd(bd_addr);
+ tAVCT_LCB* p_lcb = avct_lcb_by_bd(bd_addr);
if (p_lcb != NULL) {
/* control channel exists */
p_bcb = avct_bcb_by_lcb(p_lcb);
@@ -136,26 +132,20 @@ void avct_l2c_br_connect_ind_cback(const RawAddress& bd_addr, uint16_t lcid, uin
}
}
}
- /* else no control channel yet, reject */
-
- /* Set the FCR options: Browsing channel mandates ERTM */
- ertm_info.preferred_mode = L2CAP_FCR_ERTM_MODE;
-
- /* If we reject the connection, send DisconnectReq */
- if (result != tL2CAP_CONN::L2CAP_CONN_OK) {
- log::verbose("Connection rejected to lcid:0x{:x}", lcid);
- if (!stack::l2cap::get_interface().L2CA_DisconnectReq(lcid)) {
- log::warn("Unable to send L2CAP disconnect request cid:{}", lcid);
- }
- }
/* if result ok, proceed with connection */
if (result == tL2CAP_CONN::L2CAP_CONN_OK) {
/* store LCID */
p_bcb->ch_lcid = lcid;
-
/* transition to configuration state */
p_bcb->ch_state = AVCT_CH_CFG;
+ } else {
+ /* else no control channel yet, reject */
+ /* If we reject the connection, send DisconnectReq */
+ log::verbose("Connection rejected to lcid:0x{:x}", lcid);
+ if (!stack::l2cap::get_interface().L2CA_DisconnectReq(lcid)) {
+ log::warn("Unable to send L2CAP disconnect request cid:0x{:04x}", lcid);
+ }
}
}
@@ -174,7 +164,7 @@ void avct_br_on_l2cap_error(uint16_t lcid, uint16_t result) {
p_bcb->ch_result = result;
/* Send L2CAP disconnect req */
- avct_l2c_br_disconnect(lcid, 0);
+ avct_l2c_br_disconnect(lcid, 0 /* is_ack_needed */);
}
/*******************************************************************************
@@ -188,24 +178,23 @@ void avct_br_on_l2cap_error(uint16_t lcid, uint16_t result) {
*
******************************************************************************/
void avct_l2c_br_connect_cfm_cback(uint16_t lcid, tL2CAP_CONN result) {
- tAVCT_BCB* p_bcb;
-
/* look up bcb for this channel */
- p_bcb = avct_bcb_by_lcid(lcid);
-
- if (p_bcb == NULL) {
+ tAVCT_BCB* p_bcb = avct_bcb_by_lcid(lcid);
+ if (p_bcb == nullptr) {
+ log::warn(
+ "Received browse connect confirm callback without a browse control channel "
+ "lcid:0x{:02x} status:{}",
+ lcid, l2cap_result_code_text(result));
return;
}
- /* if in correct state */
if (p_bcb->ch_state == AVCT_CH_CONN) {
/* if result successful */
if (result == tL2CAP_CONN::L2CAP_CONN_OK) {
/* set channel state */
p_bcb->ch_state = AVCT_CH_CFG;
- }
- /* else failure */
- else {
- log::error("Invoked with non OK status");
+ } else {
+ log::error("Invoked with non OK lcid:0x{:04x} state:{} status:{}", lcid,
+ avct_ch_state_text(p_bcb->ch_state), l2cap_result_code_text(result));
}
} else if (p_bcb->conflict_lcid == lcid) {
/* we must be in AVCT_CH_CFG state for the ch_lcid channel */
@@ -214,8 +203,12 @@ void avct_l2c_br_connect_cfm_cback(uint16_t lcid, tL2CAP_CONN result) {
* disconnect req */
log::verbose("Disconnect conflict_lcid:0x{:x}", p_bcb->conflict_lcid);
if (!stack::l2cap::get_interface().L2CA_DisconnectReq(lcid)) {
- log::warn("Unable to send L2CAP disconnect request peer:{} cid:{}", p_bcb->peer_addr, lcid);
+ log::warn("Unable to send L2CAP disconnect request peer:{} lcid:0x{:04x}", p_bcb->peer_addr,
+ lcid);
}
+ } else {
+ log::error("Invoked with failure peer:{} lcid:0x{:04x} conflict_lcid:0x{:04x} status:{}",
+ p_bcb->peer_addr, lcid, p_bcb->conflict_lcid, l2cap_result_code_text(result));
}
p_bcb->conflict_lcid = 0;
}
@@ -231,19 +224,21 @@ void avct_l2c_br_connect_cfm_cback(uint16_t lcid, tL2CAP_CONN result) {
* Returns void
*
******************************************************************************/
-void avct_l2c_br_config_cfm_cback(uint16_t lcid, uint16_t /* initiator */, tL2CAP_CFG_INFO* p_cfg) {
+void avct_l2c_br_config_cfm_cback(uint16_t lcid, uint16_t initiator, tL2CAP_CFG_INFO* p_cfg) {
+ log::verbose("lcid:0x{:04x} initiator:{}", lcid, initiator);
avct_l2c_br_config_ind_cback(lcid, p_cfg);
- tAVCT_BCB* p_lcb;
-
- /* look up lcb for this channel */
- p_lcb = avct_bcb_by_lcid(lcid);
- if ((p_lcb == NULL) || (p_lcb->ch_state != AVCT_CH_CFG)) {
+ /* look up bcb for this channel */
+ tAVCT_BCB* p_bcb = avct_bcb_by_lcid(lcid);
+ if ((p_bcb == NULL) || (p_bcb->ch_state != AVCT_CH_CFG)) {
+ log::warn(
+ "Got config confirm callback with no browse channel or browse channel not in "
+ "configuration state");
return;
}
- p_lcb->ch_state = AVCT_CH_OPEN;
- avct_bcb_event(p_lcb, AVCT_LCB_LL_OPEN_EVT, NULL);
+ p_bcb->ch_state = AVCT_CH_OPEN;
+ avct_bcb_event(p_bcb, AVCT_LCB_LL_OPEN_EVT, NULL);
}
/*******************************************************************************
@@ -257,26 +252,27 @@ void avct_l2c_br_config_cfm_cback(uint16_t lcid, uint16_t /* initiator */, tL2CA
*
******************************************************************************/
void avct_l2c_br_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) {
- tAVCT_BCB* p_lcb;
- uint16_t max_mtu = BT_DEFAULT_BUFFER_SIZE - L2CAP_MIN_OFFSET - BT_HDR_SIZE;
+ log::verbose("lcid:0x{:04x}", lcid);
+ const uint16_t max_mtu = BT_DEFAULT_BUFFER_SIZE - L2CAP_MIN_OFFSET - BT_HDR_SIZE;
- /* look up lcb for this channel */
- p_lcb = avct_bcb_by_lcid(lcid);
- if (p_lcb == NULL) {
+ /* look up bcb for this channel */
+ tAVCT_BCB* p_bcb = avct_bcb_by_lcid(lcid);
+ if (p_bcb == NULL) {
+ log::warn("Unable to find browse control block lcid:0x{:02x}", lcid);
return;
}
/* store the mtu in tbl */
- p_lcb->peer_mtu = L2CAP_DEFAULT_MTU;
+ p_bcb->peer_mtu = L2CAP_DEFAULT_MTU;
if (p_cfg->mtu_present) {
- p_lcb->peer_mtu = p_cfg->mtu;
+ p_bcb->peer_mtu = p_cfg->mtu;
}
- if (p_lcb->peer_mtu > max_mtu) {
- p_lcb->peer_mtu = max_mtu;
+ if (p_bcb->peer_mtu > max_mtu) {
+ p_bcb->peer_mtu = max_mtu;
}
- log::verbose("peer_mtu:{} use:{}", p_lcb->peer_mtu, max_mtu);
+ log::verbose("peer_mtu:{} max_mtu:{}", p_bcb->peer_mtu, max_mtu);
}
/*******************************************************************************
@@ -290,41 +286,37 @@ void avct_l2c_br_config_ind_cback(uint16_t lcid, tL2CAP_CFG_INFO* p_cfg) {
*
******************************************************************************/
void avct_l2c_br_disconnect_ind_cback(uint16_t lcid, bool /* ack_needed */) {
- tAVCT_BCB* p_lcb;
uint16_t result = AVCT_RESULT_FAIL;
- /* look up lcb for this channel */
- p_lcb = avct_bcb_by_lcid(lcid);
- if (p_lcb == NULL) {
+ /* look up bcb for this channel */
+ tAVCT_BCB* p_bcb = avct_bcb_by_lcid(lcid);
+ if (p_bcb == NULL) {
return;
}
tAVCT_LCB_EVT avct_lcb_evt;
avct_lcb_evt.result = result;
- avct_bcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
+ avct_bcb_event(p_bcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
}
void avct_l2c_br_disconnect(uint16_t lcid, uint16_t result) {
if (!stack::l2cap::get_interface().L2CA_DisconnectReq(lcid)) {
- log::warn("Unable to send L2CAP disconnect request cid:{}", lcid);
+ log::warn("Unable to send L2CAP disconnect request cid:0x{:04x}", lcid);
}
- tAVCT_BCB* p_lcb;
- uint16_t res;
-
- /* look up lcb for this channel */
- p_lcb = avct_bcb_by_lcid(lcid);
- if (p_lcb == NULL) {
+ /* look up bcb for this channel */
+ tAVCT_BCB* p_bcb = avct_bcb_by_lcid(lcid);
+ if (p_bcb == NULL) {
return;
}
/* result value may be previously stored */
- res = (p_lcb->ch_result != 0) ? p_lcb->ch_result : result;
- p_lcb->ch_result = 0;
+ uint16_t res = (p_bcb->ch_result != 0) ? p_bcb->ch_result : result;
+ p_bcb->ch_result = 0;
tAVCT_LCB_EVT avct_lcb_evt;
avct_lcb_evt.result = res;
- avct_bcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
+ avct_bcb_event(p_bcb, AVCT_LCB_LL_CLOSE_EVT, &avct_lcb_evt);
}
/*******************************************************************************
@@ -338,17 +330,15 @@ void avct_l2c_br_disconnect(uint16_t lcid, uint16_t result) {
*
******************************************************************************/
void avct_l2c_br_congestion_ind_cback(uint16_t lcid, bool is_congested) {
- tAVCT_BCB* p_lcb;
-
- /* look up lcb for this channel */
- p_lcb = avct_bcb_by_lcid(lcid);
- if (p_lcb == NULL) {
+ /* look up bcb for this channel */
+ tAVCT_BCB* p_bcb = avct_bcb_by_lcid(lcid);
+ if (p_bcb == NULL) {
return;
}
tAVCT_LCB_EVT avct_lcb_evt;
avct_lcb_evt.cong = is_congested;
- avct_bcb_event(p_lcb, AVCT_LCB_LL_CONG_EVT, &avct_lcb_evt);
+ avct_bcb_event(p_bcb, AVCT_LCB_LL_CONG_EVT, &avct_lcb_evt);
}
/*******************************************************************************
@@ -362,17 +352,15 @@ void avct_l2c_br_congestion_ind_cback(uint16_t lcid, bool is_congested) {
*
******************************************************************************/
void avct_l2c_br_data_ind_cback(uint16_t lcid, BT_HDR* p_buf) {
- tAVCT_BCB* p_lcb;
- tAVCT_LCB_EVT evt_data;
-
- /* look up lcb for this channel */
- p_lcb = avct_bcb_by_lcid(lcid);
- if (p_lcb == NULL) {
+ /* look up bcb for this channel */
+ tAVCT_BCB* p_bcb = avct_bcb_by_lcid(lcid);
+ if (p_bcb == NULL) {
/* prevent buffer leak */
osi_free(p_buf);
return;
}
+ tAVCT_LCB_EVT evt_data{};
evt_data.p_buf = p_buf;
- avct_bcb_event(p_lcb, AVCT_LCB_LL_MSG_EVT, &evt_data);
+ avct_bcb_event(p_bcb, AVCT_LCB_LL_MSG_EVT, &evt_data);
}
diff --git a/system/stack/avct/avct_lcb.cc b/system/stack/avct/avct_lcb.cc
index c8e12c4f08..26d4a73160 100644
--- a/system/stack/avct/avct_lcb.cc
+++ b/system/stack/avct/avct_lcb.cc
@@ -23,18 +23,15 @@
*
******************************************************************************/
-#define LOG_TAG "avctp"
-
#include <bluetooth/log.h>
#include <string.h>
#include "avct_api.h"
#include "avct_int.h"
#include "device/include/device_iot_config.h"
+#include "include/macros.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
-#include "osi/include/osi.h"
#include "types/raw_address.h"
using namespace bluetooth;
@@ -55,6 +52,16 @@ const char* const avct_lcb_evt_str[] = {"UL_BIND_EVT", "UL_UNBIND_EVT", "UL_MS
/* lcb state machine states */
enum { AVCT_LCB_IDLE_ST, AVCT_LCB_OPENING_ST, AVCT_LCB_OPEN_ST, AVCT_LCB_CLOSING_ST };
+std::string avct_sm_state_text(const int& state) {
+ switch (state) {
+ CASE_RETURN_STRING(AVCT_LCB_IDLE_ST);
+ CASE_RETURN_STRING(AVCT_LCB_OPENING_ST);
+ CASE_RETURN_STRING(AVCT_LCB_OPEN_ST);
+ CASE_RETURN_STRING(AVCT_LCB_CLOSING_ST);
+ }
+ RETURN_UNKNOWN_TYPE_STRING(int, state);
+}
+
/* state machine action enumeration list */
enum {
AVCT_LCB_CHNL_OPEN,
@@ -163,7 +170,7 @@ void avct_lcb_event(tAVCT_LCB* p_lcb, uint8_t event, tAVCT_LCB_EVT* p_data) {
uint8_t action;
int i;
- log::verbose("LCB lcb={} event={} state={}", p_lcb->allocated, avct_lcb_evt_str[event],
+ log::verbose("LCB lcb_allocated={} event={} state={}", p_lcb->allocated, avct_lcb_evt_str[event],
avct_lcb_st_str[p_lcb->state]);
/* look up the state table for the current state */
@@ -198,22 +205,18 @@ void avct_lcb_event(tAVCT_LCB* p_lcb, uint8_t event, tAVCT_LCB_EVT* p_data) {
*
******************************************************************************/
void avct_bcb_event(tAVCT_BCB* p_bcb, uint8_t event, tAVCT_LCB_EVT* p_data) {
- tAVCT_LCB_ST_TBL state_table;
- uint8_t action;
- int i;
-
- log::verbose("BCB lcb={} event={} state={}", p_bcb->allocated, avct_lcb_evt_str[event],
- avct_lcb_st_str[p_bcb->state]);
+ log::info("BCB bcb_allocated={} event={} state={}", p_bcb->allocated, avct_lcb_evt_str[event],
+ avct_lcb_st_str[p_bcb->state]);
/* look up the state table for the current state */
- state_table = avct_lcb_st_tbl[p_bcb->state];
+ tAVCT_LCB_ST_TBL state_table = avct_lcb_st_tbl[p_bcb->state];
/* set next state */
p_bcb->state = state_table[event][AVCT_LCB_NEXT_STATE];
/* execute action functions */
- for (i = 0; i < AVCT_LCB_ACTIONS; i++) {
- action = state_table[event][i];
+ for (int i = 0; i < AVCT_LCB_ACTIONS; i++) {
+ uint8_t action = state_table[event][i];
if (action != AVCT_LCB_IGNORE) {
(*avct_bcb_action[action])(p_bcb, p_data);
} else {
@@ -247,7 +250,7 @@ tAVCT_LCB* avct_lcb_by_bd(const RawAddress& bd_addr) {
/* if no lcb found */
p_lcb = NULL;
- log::verbose("No lcb for addr {}", bd_addr);
+ log::verbose("No lcb for addr:{}", bd_addr);
}
return p_lcb;
}
@@ -270,7 +273,7 @@ tAVCT_LCB* avct_lcb_alloc(const RawAddress& bd_addr) {
if (!p_lcb->allocated) {
p_lcb->allocated = (uint8_t)(i + 1);
p_lcb->peer_addr = bd_addr;
- log::verbose("avct_lcb_alloc {}", p_lcb->allocated);
+ log::verbose("lcb_allocated:{}", p_lcb->allocated);
p_lcb->tx_q = fixed_queue_new(SIZE_MAX);
p_lcb->peer_mtu = L2CAP_LE_MIN_MTU;
break;
@@ -296,14 +299,14 @@ tAVCT_LCB* avct_lcb_alloc(const RawAddress& bd_addr) {
*
******************************************************************************/
void avct_lcb_dealloc(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* /* p_data */) {
- log::verbose("allocated: {}", p_lcb->allocated);
+ log::verbose("lcb_allocated:{}", p_lcb->allocated);
// Check if the LCB is still referenced
tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
for (size_t i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
if (p_ccb->allocated && p_ccb->p_lcb == p_lcb) {
- log::verbose("LCB in use; lcb index: {}", i);
+ log::verbose("LCB in use; lcb index:{}", i);
return;
}
}
@@ -383,8 +386,7 @@ bool avct_lcb_last_ccb(tAVCT_LCB* p_lcb, tAVCT_CCB* p_ccb_last) {
log::warn("avct_lcb_last_ccb");
for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
- log::warn("{:x}: aloc:{}, lcb:0x{}/0x{}, ccb:0x{}/0x{}", i, p_ccb->allocated,
- fmt::ptr(p_ccb->p_lcb), fmt::ptr(p_lcb), fmt::ptr(p_ccb), fmt::ptr(p_ccb_last));
+ log::warn("index:{} allocated:{}, ", i, p_ccb->allocated);
if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb != p_ccb_last)) {
return false;
}
diff --git a/system/stack/avct/avct_lcb_act.cc b/system/stack/avct/avct_lcb_act.cc
index e06bf57634..986bce7d34 100644
--- a/system/stack/avct/avct_lcb_act.cc
+++ b/system/stack/avct/avct_lcb_act.cc
@@ -33,7 +33,9 @@
#include "internal_include/bt_target.h"
#include "osi/include/allocator.h"
#include "stack/avct/avct_defs.h"
+#include "stack/include/avct_api.h"
#include "stack/include/bt_hdr.h"
+#include "stack/include/bt_psm_types.h"
#include "stack/include/bt_types.h"
#include "stack/include/l2cap_interface.h"
@@ -190,10 +192,10 @@ void avct_lcb_chnl_open(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* /* p_data */) {
p_lcb->ch_state = AVCT_CH_CONN;
if (com::android::bluetooth::flags::use_encrypt_req_for_av()) {
p_lcb->ch_lcid = stack::l2cap::get_interface().L2CA_ConnectReqWithSecurity(
- AVCT_PSM, p_lcb->peer_addr, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
+ BT_PSM_AVCTP, p_lcb->peer_addr, BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
} else {
p_lcb->ch_lcid = stack::l2cap::get_interface().L2CA_ConnectReqWithSecurity(
- AVCT_PSM, p_lcb->peer_addr, BTA_SEC_AUTHENTICATE);
+ BT_PSM_AVCTP, p_lcb->peer_addr, BTA_SEC_AUTHENTICATE);
}
if (p_lcb->ch_lcid == 0) {
/* if connect req failed, send ourselves close event */
@@ -239,7 +241,7 @@ void avct_lcb_open_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
bool is_originater = false;
for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
- if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && p_ccb->cc.role == AVCT_INT) {
+ if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && p_ccb->cc.role == AVCT_ROLE_INITIATOR) {
log::verbose("find int handle {}", i);
is_originater = true;
}
@@ -250,16 +252,16 @@ void avct_lcb_open_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
/* if ccb allocated and */
/** M: to avoid avctp collision, make sure the collision can be checked @{
*/
- log::verbose("{} ccb to lcb, alloc {}, lcb {}, role {}, pid 0x{:x}", i, p_ccb->allocated,
- fmt::ptr(p_ccb->p_lcb), p_ccb->cc.role, p_ccb->cc.pid);
+ log::verbose("{} ccb to lcb, alloc {}, role {}, pid 0x{:04x}", i, p_ccb->allocated,
+ avct_role_text(p_ccb->cc.role), p_ccb->cc.pid);
if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
/* if bound to this lcb send connect confirm event */
- if (p_ccb->cc.role == AVCT_INT) {
+ if (p_ccb->cc.role == AVCT_ROLE_INITIATOR) {
/** @} */
bind = true;
if (!stack::l2cap::get_interface().L2CA_SetTxPriority(p_lcb->ch_lcid,
L2CAP_CHNL_PRIORITY_HIGH)) {
- log::warn("Unable to set L2CAP transmit high priority peer:{} cid:{}",
+ log::warn("Unable to set L2CAP transmit high priority peer:{} lcid:0x{:04x}",
p_ccb->p_lcb->peer_addr, p_lcb->ch_lcid);
}
p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_CFM_EVT, 0,
@@ -269,7 +271,7 @@ void avct_lcb_open_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
*/
/** M: to avoid avctp collision, make sure the collision can be checked
@{ */
- else if ((p_ccb->cc.role == AVCT_ACP) && avct_lcb_has_pid(p_lcb, p_ccb->cc.pid)) {
+ else if ((p_ccb->cc.role == AVCT_ROLE_ACCEPTOR) && avct_lcb_has_pid(p_lcb, p_ccb->cc.pid)) {
/* bind ccb to lcb and send connect ind event */
if (is_originater) {
log::error("int exist, unbind acp handle:{}", i);
@@ -279,7 +281,7 @@ void avct_lcb_open_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
p_ccb->p_lcb = p_lcb;
if (!stack::l2cap::get_interface().L2CA_SetTxPriority(p_lcb->ch_lcid,
L2CAP_CHNL_PRIORITY_HIGH)) {
- log::warn("Unable to set L2CAP transmit high priority peer:{} cid:{}",
+ log::warn("Unable to set L2CAP transmit high priority peer:{} lcid:0x{:04x}",
p_ccb->p_lcb->peer_addr, p_lcb->ch_lcid);
}
p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_IND_EVT, 0,
@@ -297,7 +299,7 @@ void avct_lcb_open_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
bind = true;
if (!stack::l2cap::get_interface().L2CA_SetTxPriority(p_lcb->ch_lcid,
L2CAP_CHNL_PRIORITY_HIGH)) {
- log::warn("Unable to set L2CAP transmit high priority peer:{} cid:{}",
+ log::warn("Unable to set L2CAP transmit high priority peer:{} lcid:0x{:04x}",
p_ccb->p_lcb->peer_addr, p_lcb->ch_lcid);
}
p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_CFM_EVT, 0,
@@ -305,14 +307,14 @@ void avct_lcb_open_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
}
/* if unbound acceptor and lcb doesn't already have a ccb for this PID
*/
- else if ((p_ccb->p_lcb == NULL) && (p_ccb->cc.role == AVCT_ACP) &&
+ else if ((p_ccb->p_lcb == NULL) && (p_ccb->cc.role == AVCT_ROLE_ACCEPTOR) &&
(avct_lcb_has_pid(p_lcb, p_ccb->cc.pid) == NULL)) {
/* bind ccb to lcb and send connect ind event */
bind = true;
p_ccb->p_lcb = p_lcb;
if (!stack::l2cap::get_interface().L2CA_SetTxPriority(p_lcb->ch_lcid,
L2CAP_CHNL_PRIORITY_HIGH)) {
- log::warn("Unable to set L2CAP transmit high priority peer:{} cid:{}",
+ log::warn("Unable to set L2CAP transmit high priority peer:{} lcid:0x{:04x}",
p_ccb->p_lcb->peer_addr, p_lcb->ch_lcid);
}
p_ccb->cc.p_ctrl_cback(avct_ccb_to_idx(p_ccb), AVCT_CONNECT_IND_EVT, 0,
@@ -369,7 +371,7 @@ void avct_lcb_close_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* /* p_data */) {
for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb)) {
- if (p_ccb->cc.role == AVCT_INT) {
+ if (p_ccb->cc.role == AVCT_ROLE_INITIATOR) {
avct_ccb_dealloc(p_ccb, AVCT_DISCONNECT_IND_EVT, 0, &p_lcb->peer_addr);
} else {
p_ccb->p_lcb = NULL;
@@ -406,7 +408,7 @@ void avct_lcb_close_cfm(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
event = AVCT_DISCONNECT_IND_EVT;
}
- if (p_ccb->cc.role == AVCT_INT) {
+ if (p_ccb->cc.role == AVCT_ROLE_INITIATOR) {
avct_ccb_dealloc(p_ccb, event, p_data->result, &p_lcb->peer_addr);
} else {
p_ccb->p_lcb = NULL;
@@ -714,7 +716,7 @@ void avct_lcb_msg_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
}
/* PID not found; drop message */
- log::warn("No ccb for PID={:x}", pid);
+ log::warn("No ccb for PID=0x{:04x}", pid);
osi_free_and_reset((void**)&p_data->p_buf);
/* if command send reject */
@@ -727,7 +729,7 @@ void avct_lcb_msg_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) {
UINT16_TO_BE_STREAM(p, pid);
if (stack::l2cap::get_interface().L2CA_DataWrite(p_lcb->ch_lcid, p_buf) !=
tL2CAP_DW_RESULT::SUCCESS) {
- log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_lcb->peer_addr,
+ log::warn("Unable to write L2CAP data peer:{} lcid:0x{:04x} len:{}", p_lcb->peer_addr,
p_lcb->ch_lcid, p_buf->len);
}
}
diff --git a/system/stack/avdt/avdt_api.cc b/system/stack/avdt/avdt_api.cc
index d293517a54..6304e78255 100644
--- a/system/stack/avdt/avdt_api.cc
+++ b/system/stack/avdt/avdt_api.cc
@@ -35,6 +35,7 @@
#include "avdtc_api.h"
#include "bta/include/bta_sec_api.h"
#include "internal_include/bt_target.h"
+#include "os/logging/log_adapter.h"
#include "stack/include/a2dp_codec_api.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/l2cap_interface.h"
diff --git a/system/stack/avdt/avdt_msg.cc b/system/stack/avdt/avdt_msg.cc
index d8d5269340..4241cd741a 100644
--- a/system/stack/avdt/avdt_msg.cc
+++ b/system/stack/avdt/avdt_msg.cc
@@ -35,7 +35,6 @@
#include "avdt_int.h"
#include "avdtc_api.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/osi.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/avrc/avrc_api.cc b/system/stack/avrc/avrc_api.cc
index 60d1da067e..28f6f85064 100644
--- a/system/stack/avrc/avrc_api.cc
+++ b/system/stack/avrc/avrc_api.cc
@@ -31,7 +31,6 @@
#include "btif/include/btif_av.h"
#include "btif/include/btif_config.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/fixed_queue.h"
#include "osi/include/properties.h"
@@ -42,9 +41,6 @@
#include "storage/config_keys.h"
#include "types/raw_address.h"
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
using namespace bluetooth;
/*****************************************************************************
@@ -157,7 +153,7 @@ void avrc_flush_cmd_q(uint8_t handle) {
* Returns Nothing.
*
*****************************************************************************/
-void avrc_process_timeout(void* data) {
+static void avrc_process_timeout(void* data) {
tAVRC_PARAM* param = (tAVRC_PARAM*)data;
log::verbose("AVRC: command timeout (handle=0x{:02x}, label=0x{:02x})", param->handle,
@@ -1063,16 +1059,15 @@ uint16_t AVRC_GetProfileVersion() {
*
*****************************************************************************/
uint16_t AVRC_Open(uint8_t* p_handle, tAVRC_CONN_CB* p_ccb, const RawAddress& peer_addr) {
- uint16_t status;
- tAVCT_CC cc;
-
- cc.p_ctrl_cback = avrc_ctrl_cback; /* Control callback */
- cc.p_msg_cback = avrc_msg_cback; /* Message callback */
- cc.pid = UUID_SERVCLASS_AV_REMOTE_CONTROL; /* Profile ID */
- cc.role = p_ccb->conn; /* Initiator/acceptor role */
- cc.control = p_ccb->control; /* Control role (Control/Target) */
-
- status = AVCT_CreateConn(p_handle, &cc, peer_addr);
+ tAVCT_CC cc = {
+ .p_ctrl_cback = avrc_ctrl_cback, /* Control callback */
+ .p_msg_cback = avrc_msg_cback, /* Message callback */
+ .pid = UUID_SERVCLASS_AV_REMOTE_CONTROL, /* Profile ID */
+ .role = p_ccb->conn, /* Initiator/acceptor role */
+ .control = p_ccb->control, /* Control role (Control/Target) */
+ };
+
+ uint16_t status = AVCT_CreateConn(p_handle, &cc, peer_addr);
if (status == AVCT_SUCCESS) {
avrc_cb.ccb[*p_handle] = *p_ccb;
memset(&avrc_cb.ccb_int[*p_handle], 0, sizeof(tAVRC_CONN_INT_CB));
@@ -1081,7 +1076,8 @@ uint16_t AVRC_Open(uint8_t* p_handle, tAVRC_CONN_CB* p_ccb, const RawAddress& pe
avrc_cb.ccb_int[*p_handle].tle = alarm_new("avrcp.commandTimer");
avrc_cb.ccb_int[*p_handle].cmd_q = fixed_queue_new(SIZE_MAX);
}
- log::verbose("role: {}, control:{} status:{}, handle:{}", cc.role, cc.control, status, *p_handle);
+ log::verbose("role: {}, control:0x{:x} status:{}, handle:{}", avct_role_text(cc.role), cc.control,
+ status, *p_handle);
return status;
}
@@ -1124,7 +1120,7 @@ uint16_t AVRC_Close(uint8_t handle) {
* the connection.
*
*****************************************************************************/
-uint16_t AVRC_OpenBrowse(uint8_t handle, uint8_t conn_role) {
+uint16_t AVRC_OpenBrowse(uint8_t handle, tAVCT_ROLE conn_role) {
return AVCT_CreateBrowse(handle, conn_role);
}
diff --git a/system/stack/avrc/avrc_bld_ct.cc b/system/stack/avrc/avrc_bld_ct.cc
index 3ec2164046..a68c9dca9d 100644
--- a/system/stack/avrc/avrc_bld_ct.cc
+++ b/system/stack/avrc/avrc_bld_ct.cc
@@ -25,7 +25,6 @@
#include "avrc_defs.h"
#include "avrc_int.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_types.h"
diff --git a/system/stack/avrc/avrc_bld_tg.cc b/system/stack/avrc/avrc_bld_tg.cc
index 6390232293..a057a03b53 100644
--- a/system/stack/avrc/avrc_bld_tg.cc
+++ b/system/stack/avrc/avrc_bld_tg.cc
@@ -24,16 +24,12 @@
#include "avrc_defs.h"
#include "avrc_int.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/osi.h"
#include "stack/avct/avct_defs.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_types.h"
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
using namespace bluetooth;
/*****************************************************************************
@@ -709,7 +705,7 @@ static tAVRC_STS avrc_bld_set_absolute_volume_rsp(uint8_t abs_vol, BT_HDR* p_pkt
* Otherwise, the error code.
*
******************************************************************************/
-tAVRC_STS avrc_bld_group_navigation_rsp(uint16_t navi_id, BT_HDR* p_pkt) {
+static tAVRC_STS avrc_bld_group_navigation_rsp(uint16_t navi_id, BT_HDR* p_pkt) {
if (!AVRC_IS_VALID_GROUP(navi_id)) {
log::error("bad navigation op id: {}", navi_id);
return AVRC_STS_BAD_PARAM;
diff --git a/system/stack/avrc/avrc_pars_ct.cc b/system/stack/avrc/avrc_pars_ct.cc
index 045cee3dd2..b72fa63b43 100644
--- a/system/stack/avrc/avrc_pars_ct.cc
+++ b/system/stack/avrc/avrc_pars_ct.cc
@@ -21,14 +21,10 @@
#include "avrc_api.h"
#include "avrc_defs.h"
#include "avrc_int.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/osi.h"
#include "stack/include/bt_types.h"
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
using namespace bluetooth;
/*****************************************************************************
@@ -133,7 +129,8 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg, tAVRC_RESPONSE* p
return status;
}
-tAVRC_STS avrc_parse_notification_rsp(uint8_t* p_stream, uint16_t len, tAVRC_REG_NOTIF_RSP* p_rsp) {
+static tAVRC_STS avrc_parse_notification_rsp(uint8_t* p_stream, uint16_t len,
+ tAVRC_REG_NOTIF_RSP* p_rsp) {
uint32_t min_len = 1;
if (len < min_len) {
diff --git a/system/stack/avrc/avrc_pars_tg.cc b/system/stack/avrc/avrc_pars_tg.cc
index b178fd5acb..dd4f9bdcfe 100644
--- a/system/stack/avrc/avrc_pars_tg.cc
+++ b/system/stack/avrc/avrc_pars_tg.cc
@@ -21,7 +21,6 @@
#include "avrc_api.h"
#include "avrc_defs.h"
#include "avrc_int.h"
-#include "os/log.h"
#include "stack/include/bt_types.h"
using namespace bluetooth;
diff --git a/system/stack/avrc/avrc_sdp.cc b/system/stack/avrc/avrc_sdp.cc
index cb209dde09..61ba721b5f 100644
--- a/system/stack/avrc/avrc_sdp.cc
+++ b/system/stack/avrc/avrc_sdp.cc
@@ -28,7 +28,7 @@
#include "avrc_api.h"
#include "avrc_int.h"
-#include "os/log.h"
+#include "stack/include/bt_psm_types.h"
#include "stack/include/bt_types.h"
#include "stack/include/bt_uuid16.h"
#include "stack/include/sdp_api.h"
@@ -65,16 +65,19 @@ static uint16_t a2dp_attr_list_sdp[] = {
* Returns Nothing.
*
*****************************************************************************/
-static void avrc_sdp_cback(const RawAddress& /* bd_addr */, tSDP_STATUS status) {
- log::verbose("status: {}", status);
+static void avrc_sdp_cback(const RawAddress& bd_addr, tSDP_STATUS status) {
+ log::verbose("peer:{} status: {}", bd_addr, status);
/* reset service_uuid, so can start another find service */
avrc_cb.service_uuid = 0;
/* return info from sdp record in app callback function */
- avrc_cb.find_cback.Run(status);
-
- return;
+ if (!avrc_cb.find_cback.is_null()) {
+ avrc_cb.find_cback.Run(status);
+ } else {
+ log::warn("Received SDP callback with NULL callback peer:{} status:{}", bd_addr,
+ sdp_status_text(status));
+ }
}
/******************************************************************************
@@ -247,7 +250,7 @@ uint16_t AVRC_AddRecord(uint16_t service_uuid, const char* p_service_name,
tSDP_PROTOCOL_ELEM avrc_proto_desc_list[AVRC_NUM_PROTO_ELEMS];
avrc_proto_desc_list[0].num_params = 1;
avrc_proto_desc_list[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
- avrc_proto_desc_list[0].params[0] = AVCT_PSM;
+ avrc_proto_desc_list[0].params[0] = BT_PSM_AVCTP;
avrc_proto_desc_list[0].params[1] = 0;
for (index = 1; index < AVRC_NUM_PROTO_ELEMS; index++) {
avrc_proto_desc_list[index].num_params = 1;
@@ -271,7 +274,7 @@ uint16_t AVRC_AddRecord(uint16_t service_uuid, const char* p_service_name,
avrc_add_proto_desc_lists[i].num_elems = 2;
avrc_add_proto_desc_lists[i].list_elem[0].num_params = 1;
avrc_add_proto_desc_lists[i].list_elem[0].protocol_uuid = UUID_PROTOCOL_L2CAP;
- avrc_add_proto_desc_lists[i].list_elem[0].params[0] = AVCT_BR_PSM;
+ avrc_add_proto_desc_lists[i].list_elem[0].params[0] = BT_PSM_AVCTP_BROWSE;
avrc_add_proto_desc_lists[i].list_elem[0].params[1] = 0;
avrc_add_proto_desc_lists[i].list_elem[1].num_params = 1;
avrc_add_proto_desc_lists[i].list_elem[1].protocol_uuid = UUID_PROTOCOL_AVCTP;
diff --git a/system/stack/avrc/avrc_utils.cc b/system/stack/avrc/avrc_utils.cc
index cf2d428385..6e07b12d73 100644
--- a/system/stack/avrc/avrc_utils.cc
+++ b/system/stack/avrc/avrc_utils.cc
@@ -22,7 +22,6 @@
#include "avrc_api.h"
#include "avrc_int.h"
-#include "os/log.h"
#include "stack/include/bt_types.h"
using namespace bluetooth;
diff --git a/system/stack/btm/btm_ble_addr.cc b/system/stack/btm/btm_ble_addr.cc
index 308a69cd85..aae99cc80f 100644
--- a/system/stack/btm/btm_ble_addr.cc
+++ b/system/stack/btm/btm_ble_addr.cc
@@ -36,7 +36,6 @@
#include "crypto_toolbox/crypto_toolbox.h"
#include "hci/controller_interface.h"
#include "main/shim/entry.h"
-#include "os/log.h"
#include "stack/btm/btm_int_types.h"
#include "stack/include/acl_api.h"
#include "stack/include/bt_octets.h"
diff --git a/system/stack/btm/btm_devctl.cc b/system/stack/btm/btm_devctl.cc
index 86f4af00e4..d22fba73c7 100644
--- a/system/stack/btm/btm_devctl.cc
+++ b/system/stack/btm/btm_devctl.cc
@@ -38,7 +38,7 @@
#include "main/shim/entry.h"
#include "stack/btm/btm_int_types.h"
#include "stack/btm/btm_sec.h"
-#include "stack/gatt/connection_manager.h"
+#include "stack/connection_manager/connection_manager.h"
#include "stack/include/acl_api.h"
#include "stack/include/acl_api_types.h"
#include "stack/include/bt_types.h"
diff --git a/system/stack/btm/btm_iso_impl.h b/system/stack/btm/btm_iso_impl.h
index ddebeb9439..5e563e9860 100644
--- a/system/stack/btm/btm_iso_impl.h
+++ b/system/stack/btm/btm_iso_impl.h
@@ -33,7 +33,6 @@
#include "internal_include/stack_config.h"
#include "main/shim/entry.h"
#include "main/shim/hci_layer.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_types.h"
@@ -58,7 +57,8 @@ static constexpr uint8_t kStateFlagIsCancelled = 0x20;
constexpr char kBtmLogTag[] = "ISO";
struct iso_sync_info {
- uint16_t seq_nb;
+ uint16_t tx_seq_nb;
+ uint16_t rx_seq_nb;
};
struct iso_base {
@@ -160,7 +160,7 @@ struct iso_impl {
auto cis = std::unique_ptr<iso_cis>(new iso_cis());
cis->cig_id = cig_id;
cis->sdu_itv = sdu_itv_mtos;
- cis->sync_info = {.seq_nb = 0};
+ cis->sync_info = {.tx_seq_nb = 0, .rx_seq_nb = 0};
cis->used_credits = 0;
cis->state_flags = kStateFlagsNone;
conn_hdl_to_cis_map_[conn_handle] = std::move(cis);
@@ -529,8 +529,8 @@ struct iso_impl {
/* Calculate sequence number for the ISO data packet.
* It should be incremented by 1 every SDU Interval.
*/
- uint16_t seq_nb = iso->sync_info.seq_nb;
- iso->sync_info.seq_nb = (seq_nb + 1) & 0xffff;
+ uint16_t seq_nb = iso->sync_info.tx_seq_nb;
+ iso->sync_info.tx_seq_nb = (seq_nb + 1) & 0xffff;
if (iso_credits_ == 0 || data_len > iso_buffer_size_) {
iso->cr_stats.credits_underflow_bytes += data_len;
@@ -682,7 +682,7 @@ struct iso_impl {
auto bis = std::unique_ptr<iso_bis>(new iso_bis());
bis->big_handle = evt.big_id;
bis->sdu_itv = last_big_create_req_sdu_itv_;
- bis->sync_info = {.seq_nb = 0};
+ bis->sync_info = {.tx_seq_nb = 0, .rx_seq_nb = 0};
bis->used_credits = 0;
bis->state_flags = kStateFlagIsBroadcast;
conn_hdl_to_bis_map_[conn_handle] = std::move(bis);
@@ -807,8 +807,8 @@ struct iso_impl {
STREAM_TO_UINT16(seq_nb, stream);
- uint16_t expected_seq_nb = iso->sync_info.seq_nb;
- iso->sync_info.seq_nb = (seq_nb + 1) & 0xffff;
+ uint16_t expected_seq_nb = iso->sync_info.rx_seq_nb;
+ iso->sync_info.rx_seq_nb = (seq_nb + 1) & 0xffff;
evt.evt_lost = ((1 << 16) + seq_nb - expected_seq_nb) & 0xffff;
if (evt.evt_lost > 0) {
diff --git a/system/stack/btm/btm_sco_hci.cc b/system/stack/btm/btm_sco_hci.cc
index 81fadb5cdc..d27d823cbd 100644
--- a/system/stack/btm/btm_sco_hci.cc
+++ b/system/stack/btm/btm_sco_hci.cc
@@ -28,7 +28,6 @@
#include "bta/ag/bta_ag_int.h"
#include "btif/include/core_callbacks.h"
#include "btif/include/stack_manager_t.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/btm/btm_sco.h"
#include "udrv/include/uipc.h"
diff --git a/system/stack/btm/btm_sco_hfp_hal_linux.cc b/system/stack/btm/btm_sco_hfp_hal_linux.cc
index 018ba1fd65..9ca83962ee 100644
--- a/system/stack/btm/btm_sco_hfp_hal_linux.cc
+++ b/system/stack/btm/btm_sco_hfp_hal_linux.cc
@@ -23,7 +23,6 @@
#include "hci/controller_interface.h"
#include "main/shim/entry.h"
-#include "os/log.h"
#include "osi/include/properties.h"
#include "stack/btm/btm_sco_hfp_hal.h"
#include "stack/include/hcimsgs.h"
diff --git a/system/stack/btm/btm_sec_cb.cc b/system/stack/btm/btm_sec_cb.cc
index 3e87d19810..60a2f0398e 100644
--- a/system/stack/btm/btm_sec_cb.cc
+++ b/system/stack/btm/btm_sec_cb.cc
@@ -25,7 +25,6 @@
#include "internal_include/bt_trace.h"
#include "internal_include/stack_config.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/fixed_queue.h"
#include "osi/include/list.h"
diff --git a/system/stack/btm/btm_security_client_interface.cc b/system/stack/btm/btm_security_client_interface.cc
index a8a4a1c556..f2d397a9a7 100644
--- a/system/stack/btm/btm_security_client_interface.cc
+++ b/system/stack/btm/btm_security_client_interface.cc
@@ -19,7 +19,6 @@
#include <bluetooth/log.h>
-#include "os/log.h"
#include "stack/btm/btm_dev.h"
#include "stack/btm/btm_sec.h"
#include "stack/btm/btm_sec_cb.h"
diff --git a/system/stack/btm/hfp_lc3_decoder.cc b/system/stack/btm/hfp_lc3_decoder.cc
index 30e30d1ffc..245527b0dc 100644
--- a/system/stack/btm/hfp_lc3_decoder.cc
+++ b/system/stack/btm/hfp_lc3_decoder.cc
@@ -23,7 +23,6 @@
#include <cstring>
-#include "os/log.h"
#include "osi/include/allocator.h"
using namespace bluetooth;
diff --git a/system/stack/btm/hfp_lc3_decoder_linux.cc b/system/stack/btm/hfp_lc3_decoder_linux.cc
index b30da4ff19..0ba81c9dd0 100644
--- a/system/stack/btm/hfp_lc3_decoder_linux.cc
+++ b/system/stack/btm/hfp_lc3_decoder_linux.cc
@@ -23,7 +23,6 @@
#include "hfp_lc3_decoder.h"
#include "mmc/codec_client/codec_client.h"
#include "mmc/proto/mmc_config.pb.h"
-#include "os/log.h"
using namespace bluetooth;
diff --git a/system/stack/btm/hfp_lc3_encoder.cc b/system/stack/btm/hfp_lc3_encoder.cc
index 6e0cdb28df..9d909fef0d 100644
--- a/system/stack/btm/hfp_lc3_encoder.cc
+++ b/system/stack/btm/hfp_lc3_encoder.cc
@@ -23,7 +23,6 @@
#include <cstring>
-#include "os/log.h"
#include "osi/include/allocator.h"
using namespace bluetooth;
diff --git a/system/stack/btm/hfp_lc3_encoder_linux.cc b/system/stack/btm/hfp_lc3_encoder_linux.cc
index 448e6403c2..21f8d55d68 100644
--- a/system/stack/btm/hfp_lc3_encoder_linux.cc
+++ b/system/stack/btm/hfp_lc3_encoder_linux.cc
@@ -21,7 +21,6 @@
#include "hfp_lc3_encoder.h"
#include "mmc/codec_client/codec_client.h"
#include "mmc/proto/mmc_config.pb.h"
-#include "os/log.h"
using namespace bluetooth;
diff --git a/system/stack/btm/hfp_msbc_decoder.cc b/system/stack/btm/hfp_msbc_decoder.cc
index 334cf91f9f..d1396a771d 100644
--- a/system/stack/btm/hfp_msbc_decoder.cc
+++ b/system/stack/btm/hfp_msbc_decoder.cc
@@ -24,7 +24,6 @@
#include "embdrv/sbc/decoder/include/oi_codec_sbc.h"
#include "embdrv/sbc/decoder/include/oi_status.h"
-#include "os/log.h"
#define HFP_MSBC_PKT_LEN 60
#define HFP_MSBC_PCM_BYTES 240
diff --git a/system/stack/btm/security_device_record.h b/system/stack/btm/security_device_record.h
index 14463ac211..c1037a40f4 100644
--- a/system/stack/btm/security_device_record.h
+++ b/system/stack/btm/security_device_record.h
@@ -26,7 +26,7 @@
#include "internal_include/bt_target.h"
#include "macros.h"
-#include "os/log.h"
+#include "os/logging/log_adapter.h"
#include "stack/include/bt_device_type.h"
#include "stack/include/bt_name.h"
#include "stack/include/bt_octets.h"
diff --git a/system/stack/btu/main_thread.cc b/system/stack/btu/main_thread.cc
index 03afc210f5..6223e66716 100644
--- a/system/stack/btu/main_thread.cc
+++ b/system/stack/btu/main_thread.cc
@@ -27,7 +27,6 @@
#include "common/message_loop_thread.h"
#include "include/hardware/bluetooth.h"
-#include "os/log.h"
using bluetooth::common::MessageLoopThread;
using namespace bluetooth;
diff --git a/system/stack/gatt/connection_manager.cc b/system/stack/connection_manager/connection_manager.cc
index 96278a9106..c29ac5d403 100644
--- a/system/stack/gatt/connection_manager.cc
+++ b/system/stack/connection_manager/connection_manager.cc
@@ -581,7 +581,10 @@ void dump(int fd) {
dprintf(fd, "\tdevices attempting connection: %d", (int)bgconn_dev.size());
for (const auto& entry : bgconn_dev) {
// TODO: confirm whether we need to replace this
- dprintf(fd, "\n\t * %s: ", ADDRESS_TO_LOGGABLE_CSTR(entry.first));
+ dprintf(fd, "\n\t * %s:\t\tin_accept_list: %s\t cap_targeted_announcements: %s",
+ ADDRESS_TO_LOGGABLE_CSTR(entry.first),
+ entry.second.is_in_accept_list ? "true" : "false",
+ entry.second.doing_targeted_announcements_conn.empty() ? "false" : "true");
if (!entry.second.doing_direct_conn.empty()) {
dprintf(fd, "\n\t\tapps doing direct connect: ");
@@ -596,14 +599,6 @@ void dump(int fd) {
dprintf(fd, "%d, ", id);
}
}
- if (!entry.second.doing_targeted_announcements_conn.empty()) {
- dprintf(fd, "\n\t\tapps doing cap announcement connect: ");
- for (const auto& id : entry.second.doing_targeted_announcements_conn) {
- dprintf(fd, "%d, ", id);
- }
- }
- dprintf(fd, "\n\t\t is in the allow list: %s",
- entry.second.is_in_accept_list ? "true" : "false");
}
dprintf(fd, "\n");
}
diff --git a/system/stack/gatt/connection_manager.h b/system/stack/connection_manager/connection_manager.h
index a9a5256261..a9a5256261 100644
--- a/system/stack/gatt/connection_manager.h
+++ b/system/stack/connection_manager/connection_manager.h
diff --git a/system/stack/fuzzers/avrc_fuzzer.cc b/system/stack/fuzzers/avrc_fuzzer.cc
index 1592b707fd..be0c80f32c 100644
--- a/system/stack/fuzzers/avrc_fuzzer.cc
+++ b/system/stack/fuzzers/avrc_fuzzer.cc
@@ -20,18 +20,17 @@
#include <cstdint>
#include <functional>
-#include <optional>
#include <vector>
#include "osi/include/allocator.h"
#include "stack/include/avct_api.h"
#include "stack/include/avrc_api.h"
+#include "stack/include/bt_psm_types.h"
#include "test/fake/fake_osi.h"
#include "test/mock/mock_btif_config.h"
#include "test/mock/mock_stack_acl.h"
#include "test/mock/mock_stack_btm_dev.h"
#include "test/mock/mock_stack_l2cap_api.h"
-#include "test/mock/mock_stack_l2cap_ble.h"
#include "types/bluetooth/uuid.h"
// TODO(b/369381361) Enfore -Wmissing-prototypes
@@ -81,11 +80,11 @@ public:
[](uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, bool enable_snoop,
tL2CAP_ERTM_INFO* p_ertm_info, uint16_t my_mtu, uint16_t required_remote_mtu,
uint16_t sec_level) {
- log::assert_that(psm == AVCT_PSM || psm == AVCT_BR_PSM,
- "assert failed: psm == AVCT_PSM || psm == AVCT_BR_PSM");
- if (psm == AVCT_PSM) {
+ log::assert_that(psm == BT_PSM_AVCTP || psm == BT_PSM_AVCTP_BROWSE,
+ "assert failed: psm == BT_PSM_AVCTP || psm == BT_PSM_AVCTP_BROWSE");
+ if (psm == BT_PSM_AVDTP) {
avct_appl = p_cb_info;
- } else if (psm == AVCT_BR_PSM) {
+ } else if (psm == BT_PSM_AVCTP_BROWSE) {
avct_br_appl = p_cb_info;
}
return psm;
@@ -186,7 +185,7 @@ static void Fuzz(const uint8_t* data, size_t size) {
tAVRC_CONN_CB ccb = {
.ctrl_cback = base::Bind(ctrl_cb),
.msg_cback = base::Bind(msg_cb),
- .conn = (uint8_t)(is_initiator ? AVCT_INT : AVCT_ACP),
+ .conn = (is_initiator ? AVCT_ROLE_INITIATOR : AVCT_ROLE_ACCEPTOR),
.control = (uint8_t)(is_controller ? AVCT_CONTROL : AVCT_TARGET),
};
diff --git a/system/stack/fuzzers/l2cap_fuzzer.cc b/system/stack/fuzzers/l2cap_fuzzer.cc
index fd68f98486..2c5c3d2cde 100644
--- a/system/stack/fuzzers/l2cap_fuzzer.cc
+++ b/system/stack/fuzzers/l2cap_fuzzer.cc
@@ -36,6 +36,7 @@
#include "stack/include/l2cap_interface.h"
#include "stack/include/l2cap_module.h"
#include "stack/include/l2cdefs.h"
+#include "stack/l2cap/l2c_int.h"
#include "test/fake/fake_osi.h"
#include "test/mock/mock_main_shim_entry.h"
#include "test/mock/mock_stack_acl.h"
@@ -161,8 +162,6 @@ constexpr uint16_t kSmpBrHndl = 0x0222;
constexpr uint16_t kNumClassicAclBuffer = 100;
constexpr uint16_t kNumLeAclBuffer = 100;
-void l2c_link_hci_conn_comp(tHCI_STATUS status, uint16_t handle, const RawAddress& p_bda);
-
static void Fuzz(const uint8_t* data, size_t size) {
memset(&btm_cb, 0, sizeof(btm_cb));
diff --git a/system/stack/gatt/gatt_api.cc b/system/stack/gatt/gatt_api.cc
index d9d7f051d9..7ed0fe0516 100644
--- a/system/stack/gatt/gatt_api.cc
+++ b/system/stack/gatt/gatt_api.cc
@@ -37,7 +37,7 @@
#include "osi/include/allocator.h"
#include "stack/arbiter/acl_arbiter.h"
#include "stack/btm/btm_dev.h"
-#include "stack/gatt/connection_manager.h"
+#include "stack/connection_manager/connection_manager.h"
#include "stack/gatt/gatt_int.h"
#include "stack/include/ais_api.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/gatt/gatt_int.h b/system/stack/gatt/gatt_int.h
index 485c7f6a34..59dc338b5d 100644
--- a/system/stack/gatt/gatt_int.h
+++ b/system/stack/gatt/gatt_int.h
@@ -34,6 +34,7 @@
#include "gatt_api.h"
#include "internal_include/bt_target.h"
#include "macros.h"
+#include "os/logging/log_adapter.h"
#include "osi/include/fixed_queue.h"
#include "stack/include/bt_hdr.h"
#include "types/bluetooth/uuid.h"
diff --git a/system/stack/gatt/gatt_main.cc b/system/stack/gatt/gatt_main.cc
index bc559a5715..f5591d2194 100644
--- a/system/stack/gatt/gatt_main.cc
+++ b/system/stack/gatt/gatt_main.cc
@@ -28,7 +28,6 @@
#include "btif/include/btif_dm.h"
#include "btif/include/btif_storage.h"
#include "btif/include/stack_manager_t.h"
-#include "connection_manager.h"
#include "device/include/interop.h"
#include "internal_include/bt_target.h"
#include "internal_include/stack_config.h"
@@ -38,6 +37,7 @@
#include "stack/arbiter/acl_arbiter.h"
#include "stack/btm/btm_dev.h"
#include "stack/btm/btm_sec.h"
+#include "stack/connection_manager/connection_manager.h"
#include "stack/eatt/eatt.h"
#include "stack/gatt/gatt_int.h"
#include "stack/include/acl_api.h"
diff --git a/system/stack/gatt/gatt_utils.cc b/system/stack/gatt/gatt_utils.cc
index 72083acb50..d159bbd794 100644
--- a/system/stack/gatt/gatt_utils.cc
+++ b/system/stack/gatt/gatt_utils.cc
@@ -38,8 +38,8 @@
#include "osi/include/properties.h"
#include "stack/btm/btm_dev.h"
#include "stack/btm/btm_sec.h"
+#include "stack/connection_manager/connection_manager.h"
#include "stack/eatt/eatt.h"
-#include "stack/gatt/connection_manager.h"
#include "stack/gatt/gatt_int.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_psm_types.h"
diff --git a/system/stack/hid/hidd_api.cc b/system/stack/hid/hidd_api.cc
index 3a213d4c1d..79f4d1d7b0 100644
--- a/system/stack/hid/hidd_api.cc
+++ b/system/stack/hid/hidd_api.cc
@@ -34,7 +34,6 @@
#include "hidd_int.h"
#include "hiddefs.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_psm_types.h"
#include "stack/include/bt_types.h"
diff --git a/system/stack/hid/hidh_api.cc b/system/stack/hid/hidh_api.cc
index 72c30e3f13..f415c48fb1 100644
--- a/system/stack/hid/hidh_api.cc
+++ b/system/stack/hid/hidh_api.cc
@@ -34,7 +34,6 @@
#include "hiddefs.h"
#include "hidh_int.h"
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_uuid16.h"
diff --git a/system/stack/include/avct_api.h b/system/stack/include/avct_api.h
index 0ac2399b93..3693cdcd0f 100644
--- a/system/stack/include/avct_api.h
+++ b/system/stack/include/avct_api.h
@@ -26,8 +26,9 @@
#define AVCT_API_H
#include <cstdint>
+#include <string>
-#include "internal_include/bt_target.h"
+#include "include/macros.h"
#include "stack/include/bt_hdr.h"
#include "types/raw_address.h"
@@ -42,10 +43,6 @@
#define AVCT_PID_IN_USE 3 /* PID already in use */
#define AVCT_NOT_OPEN 4 /* Connection not open */
-/* PSM for AVCT. */
-#define AVCT_PSM 0x0017
-#define AVCT_BR_PSM 0x001B
-
/* Protocol revision numbers */
#define AVCT_REV_1_0 0x0100
#define AVCT_REV_1_2 0x0102
@@ -69,8 +66,18 @@
#define AVCT_BROWSE_OFFSET 17 /* the default offset for browsing channel */
/* Connection role. */
-#define AVCT_INT 0 /* Initiator connection */
-#define AVCT_ACP 1 /* Acceptor connection */
+typedef enum {
+ AVCT_ROLE_INITIATOR = 0, /* Initiator connection */
+ AVCT_ROLE_ACCEPTOR = 1, /* Acceptor connection */
+} tAVCT_ROLE;
+
+inline std::string avct_role_text(const tAVCT_ROLE& role) {
+ switch (role) {
+ CASE_RETURN_TEXT(AVCT_ROLE_INITIATOR);
+ CASE_RETURN_TEXT(AVCT_ROLE_ACCEPTOR);
+ }
+ RETURN_UNKNOWN_TYPE_STRING(tAVCT_ROLE, role);
+}
/* Control role. */
#define AVCT_TARGET 1 /* target */
@@ -116,7 +123,7 @@ typedef struct {
tAVCT_CTRL_CBACK* p_ctrl_cback; /* Control callback */
tAVCT_MSG_CBACK* p_msg_cback; /* Message callback */
uint16_t pid; /* Profile ID */
- uint8_t role; /* Initiator/acceptor role */
+ tAVCT_ROLE role; /* Initiator/acceptor role */
uint8_t control; /* Control role (Control/Target) */
} tAVCT_CC;
@@ -207,7 +214,7 @@ uint16_t AVCT_RemoveConn(uint8_t handle);
* Returns AVCT_SUCCESS if successful, otherwise error.
*
******************************************************************************/
-uint16_t AVCT_CreateBrowse(uint8_t handle, uint8_t role);
+uint16_t AVCT_CreateBrowse(uint8_t handle, tAVCT_ROLE role);
/*******************************************************************************
*
@@ -273,4 +280,18 @@ uint16_t AVCT_GetPeerMtu(uint8_t handle);
******************************************************************************/
uint16_t AVCT_MsgReq(uint8_t handle, uint8_t label, uint8_t cr, BT_HDR* p_msg);
+/*******************************************************************************
+**
+** Function AVCT_Dumpsys
+**
+** Description This function provides dumpsys data during the dumpsys
+** procedure.
+**
+** Parameters: fd: Descriptor used to write the AVCT internals
+**
+** Returns void
+**
+*******************************************************************************/
+void AVCT_Dumpsys(int fd);
+
#endif /* AVCT_API_H */
diff --git a/system/stack/include/avdt_api.h b/system/stack/include/avdt_api.h
index 30a7ebea26..c1275db105 100644
--- a/system/stack/include/avdt_api.h
+++ b/system/stack/include/avdt_api.h
@@ -33,7 +33,6 @@
#include "internal_include/bt_target.h"
#include "macros.h"
-#include "os/log.h"
#include "stack/include/bt_hdr.h"
#include "types/raw_address.h"
diff --git a/system/stack/include/avrc_api.h b/system/stack/include/avrc_api.h
index 918bdfb436..589ddb5021 100644
--- a/system/stack/include/avrc_api.h
+++ b/system/stack/include/avrc_api.h
@@ -65,12 +65,6 @@
/* If conflict, allow the other side to succeed */
#define AVRC_CT_PASSIVE 4
-/* Connection role */
-/* initiator */
-#define AVRC_CONN_INT AVCT_INT
-/* Acceptor */
-#define AVRC_CONN_ACP AVCT_ACP
-
/* AVRC CTRL events */
/* AVRC_OPEN_IND_EVT event is sent when the connection is successfully opened.
* This eventis sent in response to an AVRC_Open(). */
@@ -201,7 +195,7 @@ typedef struct {
* attribute filter
* to be ATTR_ID_SERVICE_CLASS_ID_LIST,
* ATTR_ID_BT_PROFILE_DESC_LIST,
- * ATTR_ID_SUPPORTED_FEATURES, ATTR_ID_SERVICE_NAME and
+ * ATTR_ID_SUPPORTED_FEATURES, ATTR_ID_SERVICE_NAME,
* ATTR_ID_PROVIDER_NAME.
* If not NULL, the input is taken as the filter. */
} tAVRC_SDP_DB_PARAMS;
@@ -229,7 +223,7 @@ typedef struct {
tAVRC_CTRL_CBACK ctrl_cback; /* application control callback */
tAVRC_MSG_CBACK msg_cback; /* application message callback */
uint32_t company_id; /* the company ID */
- uint8_t conn; /* Connection role (Initiator/acceptor) */
+ tAVCT_ROLE conn; /* Connection role (Initiator/acceptor) */
uint8_t control; /* Control role (Control/Target) */
} tAVRC_CONN_CB;
@@ -460,7 +454,7 @@ uint16_t AVRC_Close(uint8_t handle);
* the connection.
*
*****************************************************************************/
-uint16_t AVRC_OpenBrowse(uint8_t handle, uint8_t conn_role);
+uint16_t AVRC_OpenBrowse(uint8_t handle, tAVCT_ROLE conn_role);
/******************************************************************************
*
diff --git a/system/stack/include/bt_psm_types.h b/system/stack/include/bt_psm_types.h
index a5bb3e47e4..3f0716110b 100644
--- a/system/stack/include/bt_psm_types.h
+++ b/system/stack/include/bt_psm_types.h
@@ -36,9 +36,9 @@ enum tBT_PSM : uint16_t {
BT_PSM_UPNP = 0x0015,
BT_PSM_AVCTP = 0x0017,
BT_PSM_AVDTP = 0x0019,
- BT_PSM_AVCTP_13 = 0x001B, /* Advanced Control - Browsing */
- BT_PSM_UDI_CP = 0x001D, /* Unrestricted Digital Information Profile C-Plane */
- BT_PSM_ATT = 0x001F, /* Attribute Protocol */
+ BT_PSM_AVCTP_BROWSE = 0x001B, /* Advanced Control - Browsing */
+ BT_PSM_UDI_CP = 0x001D, /* Unrestricted Digital Information Profile C-Plane */
+ BT_PSM_ATT = 0x001F, /* Attribute Protocol */
BT_PSM_EATT = 0x0027,
/* We will not allocate a PSM in the reserved range to 3rd party apps
*/
@@ -58,7 +58,7 @@ inline std::string bt_psm_text(const tBT_PSM& psm) {
CASE_RETURN_STRING_HEX04(BT_PSM_UPNP);
CASE_RETURN_STRING_HEX04(BT_PSM_AVCTP);
CASE_RETURN_STRING_HEX04(BT_PSM_AVDTP);
- CASE_RETURN_STRING_HEX04(BT_PSM_AVCTP_13);
+ CASE_RETURN_STRING_HEX04(BT_PSM_AVCTP_BROWSE);
CASE_RETURN_STRING_HEX04(BT_PSM_UDI_CP);
CASE_RETURN_STRING_HEX04(BT_PSM_ATT);
CASE_RETURN_STRING_HEX04(BT_PSM_EATT);
diff --git a/system/stack/include/l2cap_acl_interface.h b/system/stack/include/l2cap_acl_interface.h
index 811b5c1288..7751d14255 100644
--- a/system/stack/include/l2cap_acl_interface.h
+++ b/system/stack/include/l2cap_acl_interface.h
@@ -32,9 +32,6 @@ void acl_write_automatic_flush_timeout(const RawAddress& bd_addr, uint16_t flush
// ACL data received from HCI-ACL
void l2c_rcv_acl_data(BT_HDR* p_msg);
-// Segments is sent to HCI-ACL
-void l2c_link_segments_xmitted(BT_HDR* p_msg);
-
void l2cu_resubmit_pending_sec_req(const RawAddress* p_bda);
void l2c_packets_completed(uint16_t handle, uint16_t num_sent);
diff --git a/system/stack/include/l2cap_hci_link_interface.h b/system/stack/include/l2cap_hci_link_interface.h
index 978aadade5..8699d1aa03 100644
--- a/system/stack/include/l2cap_hci_link_interface.h
+++ b/system/stack/include/l2cap_hci_link_interface.h
@@ -47,9 +47,6 @@ void l2cble_notify_le_connection(const RawAddress& bda);
void l2cble_use_preferred_conn_params(const RawAddress& bda);
-void l2cble_process_rc_param_request_evt(uint16_t handle, uint16_t int_min, uint16_t int_max,
- uint16_t latency, uint16_t timeout);
-
// Invoked when HCI mode is changed to HCI_MODE_ACTIVE or HCI_MODE_SNIFF
void l2c_OnHciModeChangeSendPendingPackets(RawAddress remote);
diff --git a/system/stack/l2cap/l2c_api.cc b/system/stack/l2cap/l2c_api.cc
index cb66ec209d..a233046a74 100644
--- a/system/stack/l2cap/l2c_api.cc
+++ b/system/stack/l2cap/l2c_api.cc
@@ -45,13 +45,11 @@
#include "stack/include/bt_hdr.h"
#include "stack/include/bt_psm_types.h"
#include "stack/include/btm_client_interface.h"
+#include "stack/include/l2cap_module.h"
#include "stack/include/main_thread.h"
#include "stack/l2cap/l2c_int.h"
#include "types/raw_address.h"
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
using namespace bluetooth;
extern fixed_queue_t* btu_general_alarm_queue;
@@ -59,13 +57,6 @@ tL2C_AVDT_CHANNEL_INFO av_media_channels[MAX_ACTIVE_AVDT_CONN];
constexpr uint16_t L2CAP_LE_CREDIT_THRESHOLD = 64;
-tBT_TRANSPORT l2c_get_transport_from_fixed_cid(uint16_t fixed_cid) {
- if (fixed_cid >= L2CAP_ATT_CID && fixed_cid <= L2CAP_SMP_CID) {
- return BT_TRANSPORT_LE;
- }
- return BT_TRANSPORT_BR_EDR;
-}
-
uint16_t L2CA_RegisterWithSecurity(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
uint16_t my_mtu, uint16_t required_remote_mtu,
diff --git a/system/stack/l2cap/l2c_ble.cc b/system/stack/l2cap/l2c_ble.cc
index a00e0d17f4..9d69e5ab36 100644
--- a/system/stack/l2cap/l2c_ble.cc
+++ b/system/stack/l2cap/l2c_ble.cc
@@ -44,7 +44,7 @@
#include "stack/btm/btm_int_types.h"
#include "stack/btm/btm_sec.h"
#include "stack/btm/btm_sec_int_types.h"
-#include "stack/gatt/connection_manager.h"
+#include "stack/connection_manager/connection_manager.h"
#include "stack/include/acl_api.h"
#include "stack/include/bt_psm_types.h"
#include "stack/include/bt_types.h"
@@ -53,21 +53,18 @@
#include "stack/include/btm_log_history.h"
#include "stack/include/btm_status.h"
#include "stack/include/l2cap_acl_interface.h"
+#include "stack/include/l2cap_controller_interface.h"
+#include "stack/include/l2cap_hci_link_interface.h"
#include "stack/include/l2cap_interface.h"
#include "stack/include/l2cdefs.h"
#include "stack/include/main_thread.h"
#include "stack/l2cap/l2c_int.h"
#include "types/raw_address.h"
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
using namespace bluetooth;
namespace {
-
constexpr char kBtmLogTag[] = "L2CAP";
-
}
extern tBTM_CB btm_cb;
@@ -1280,8 +1277,8 @@ void l2cble_send_peer_disc_req(tL2C_CCB* p_ccb) {
* Returns void
*
******************************************************************************/
-void l2cble_sec_comp(RawAddress bda, tBT_TRANSPORT transport, void* /* p_ref_data */,
- tBTM_STATUS btm_status) {
+static void l2cble_sec_comp(RawAddress bda, tBT_TRANSPORT transport, void* /* p_ref_data */,
+ tBTM_STATUS btm_status) {
tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bda, BT_TRANSPORT_LE);
tL2CAP_SEC_DATA* p_buf = NULL;
uint8_t sec_act;
diff --git a/system/stack/l2cap/l2c_ble_conn_params.cc b/system/stack/l2cap/l2c_ble_conn_params.cc
index f617e59d5d..1e9d4ba7ab 100644
--- a/system/stack/l2cap/l2c_ble_conn_params.cc
+++ b/system/stack/l2cap/l2c_ble_conn_params.cc
@@ -38,14 +38,12 @@
#include "stack/include/acl_api.h"
#include "stack/include/btm_ble_api_types.h"
#include "stack/include/btm_client_interface.h"
+#include "stack/include/l2cap_hci_link_interface.h"
#include "stack/include/l2cap_interface.h"
#include "stack/include/main_thread.h"
#include "stack/l2cap/l2c_int.h"
#include "types/raw_address.h"
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
using namespace bluetooth;
void l2cble_start_conn_update(tL2C_LCB* p_lcb);
diff --git a/system/stack/l2cap/l2c_csm.cc b/system/stack/l2cap/l2c_csm.cc
index 1c7021ffc7..776596a6f5 100644
--- a/system/stack/l2cap/l2c_csm.cc
+++ b/system/stack/l2cap/l2c_csm.cc
@@ -66,6 +66,75 @@ static void l2c_csm_send_connect_rsp(tL2C_CCB* p_ccb) {
l2c_csm_execute(p_ccb, L2CEVT_L2CA_CONNECT_RSP, NULL);
}
+#if (L2CAP_CONFORMANCE_TESTING == TRUE)
+#include "osi/include/properties.h"
+
+/* FCS Flag configuration for L2CAP/FOC/BV-04 and L2CAP/FOC/BV-05
+ * Upper tester implementation for above two testcases where
+ * different FCS options need to be used in different steps.
+ */
+
+/* L2CAP.TSp38, table 4.13 */
+static uint8_t pts_fcs_option_bv_04_c[] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+
+/* L2CAP.TSp38, table 4.68 */
+static uint8_t pts_fcs_option_bv_05_c[] = {0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+
+static uint8_t pts_foc_bv_test_id_property;
+
+static uint8_t pts_get_fcs_option(void) {
+ static size_t fcs_opt_iter = 0;
+ uint8_t* fcs_test_options = nullptr;
+ uint8_t iter_cnt = 0;
+
+ uint8_t test_id = osi_property_get_int32("bluetooth.pts.l2cap.foc.bv.test", 0);
+ if (pts_foc_bv_test_id_property != test_id) {
+ pts_foc_bv_test_id_property = test_id;
+ fcs_opt_iter = 0;
+ }
+
+ switch (test_id) {
+ case 4:
+ log::info("Proceed test L2CAP/FOC/BV-04-C");
+ fcs_test_options = &pts_fcs_option_bv_04_c[0];
+ iter_cnt = sizeof(pts_fcs_option_bv_04_c);
+ break;
+ case 5:
+ log::info("Proceed test L2CAP/FOC/BV-05-C");
+ fcs_test_options = &pts_fcs_option_bv_05_c[0];
+ iter_cnt = sizeof(pts_fcs_option_bv_05_c);
+ break;
+ default:
+ log::info("Proceed unknown test");
+ return 1;
+ }
+
+ log::info("fcs_opt_iter: {}, fcs option: {}", fcs_opt_iter,
+ fcs_opt_iter < iter_cnt ? fcs_test_options[fcs_opt_iter] : -1);
+
+ if (fcs_opt_iter < iter_cnt) {
+ return fcs_test_options[fcs_opt_iter++];
+ }
+
+ log::info("Too many iterations: {}, return fcs = 0x01", fcs_opt_iter);
+ return 1;
+}
+
+static void l2c_csm_send_config_req(tL2C_CCB* p_ccb);
+static void l2c_ccb_pts_delay_config_timeout(void* data) {
+ tL2C_CCB* p_ccb = (tL2C_CCB*)data;
+ l2c_csm_send_config_req(p_ccb);
+}
+#endif
+
+static uint8_t get_fcs_option(void) {
+#if (L2CAP_CONFORMANCE_TESTING == TRUE)
+ return pts_get_fcs_option();
+#else
+ return 0x01;
+#endif
+}
+
// Send a config request and adjust the state machine
static void l2c_csm_send_config_req(tL2C_CCB* p_ccb) {
tL2CAP_CFG_INFO config{};
@@ -80,7 +149,7 @@ static void l2c_csm_send_config_req(tL2C_CCB* p_ccb) {
/* Later l2cu_process_our_cfg_req() will check if remote supports it, and if not, it will be
* cleared as per spec. */
config.fcs_present = true;
- config.fcs = 1;
+ config.fcs = get_fcs_option();
}
}
p_ccb->our_cfg = config;
@@ -506,7 +575,13 @@ static void l2c_csm_term_w4_sec_comp(tL2C_CCB* p_ccb, tL2CEVT event, void* p_dat
if (p_ccb->p_lcb->transport != BT_TRANSPORT_LE) {
log::debug("Not LE connection, sending configure request");
l2c_csm_send_connect_rsp(p_ccb);
+#if (L2CAP_CONFORMANCE_TESTING == TRUE)
+ // TODO: when b/374014194 is solved on PTS side, revert change adding this delay.
+ alarm_set_on_mloop(p_ccb->pts_config_delay_timer, 5000, l2c_ccb_pts_delay_config_timeout,
+ p_ccb);
+#else
l2c_csm_send_config_req(p_ccb);
+#endif
} else {
if (p_ccb->ecoc) {
/* Handle Credit Based Connection */
diff --git a/system/stack/l2cap/l2c_int.h b/system/stack/l2cap/l2c_int.h
index 94396b7577..02a1fa66ad 100644
--- a/system/stack/l2cap/l2c_int.h
+++ b/system/stack/l2cap/l2c_int.h
@@ -282,6 +282,11 @@ struct tL2C_CCB {
alarm_t* l2c_ccb_timer; /* CCB Timer Entry */
+#if (L2CAP_CONFORMANCE_TESTING == TRUE)
+ alarm_t* pts_config_delay_timer; /* Used to delay sending CONFIGURATION_REQ to overcome PTS issue
+ */
+#endif
+
tL2C_RCB* p_rcb; /* Registration CB for this Channel */
#define IB_CFG_DONE 0x01
@@ -779,11 +784,12 @@ void l2cu_adjust_out_mps(tL2C_CCB* p_ccb);
/* Functions provided by l2c_link.cc
***********************************
*/
+
void l2c_link_timeout(tL2C_LCB* p_lcb);
void l2c_info_resp_timer_timeout(void* data);
void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, uint16_t local_cid, BT_HDR* p_buf);
void l2c_link_adjust_allocation(void);
-
+void l2c_link_hci_conn_comp(tHCI_STATUS status, uint16_t handle, const RawAddress& p_bda);
void l2c_link_sec_comp(RawAddress p_bda, tBT_TRANSPORT transport, void* p_ref_data,
tBTM_STATUS status);
void l2c_link_adjust_chnl_allocation(void);
@@ -827,10 +833,11 @@ void l2c_fcr_stop_timer(tL2C_CCB* p_ccb);
/* Functions provided by l2c_ble.cc
***********************************
*/
+
bool l2cble_create_conn(tL2C_LCB* p_lcb);
void l2cble_process_sig_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len);
void l2c_ble_link_adjust_allocation(void);
-
+void l2cble_start_conn_update(tL2C_LCB* p_lcb);
void l2cble_credit_based_conn_req(tL2C_CCB* p_ccb);
void l2cble_credit_based_conn_res(tL2C_CCB* p_ccb, tL2CAP_LE_RESULT_CODE result);
void l2cble_send_peer_disc_req(tL2C_CCB* p_ccb);
diff --git a/system/stack/l2cap/l2c_link.cc b/system/stack/l2cap/l2c_link.cc
index b7521ab677..3a3bb4290d 100644
--- a/system/stack/l2cap/l2c_link.cc
+++ b/system/stack/l2cap/l2c_link.cc
@@ -40,15 +40,13 @@
#include "stack/include/btm_status.h"
#include "stack/include/hci_error_code.h"
#include "stack/include/l2cap_acl_interface.h"
+#include "stack/include/l2cap_controller_interface.h"
#include "stack/include/l2cap_hci_link_interface.h"
#include "stack/include/l2cap_security_interface.h"
#include "stack/l2cap/l2c_int.h"
#include "types/bt_transport.h"
#include "types/raw_address.h"
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
using namespace bluetooth;
extern tBTM_CB btm_cb;
@@ -1151,45 +1149,6 @@ void l2c_packets_completed(uint16_t handle, uint16_t num_sent) {
}
}
-/*******************************************************************************
- *
- * Function l2c_link_segments_xmitted
- *
- * Description This function is called from the HCI Interface when an ACL
- * data packet segment is transmitted.
- *
- * Returns void
- *
- ******************************************************************************/
-void l2c_link_segments_xmitted(BT_HDR* p_msg) {
- uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
-
- /* Extract the handle */
- uint16_t handle{HCI_INVALID_HANDLE};
- STREAM_TO_UINT16(handle, p);
- handle = HCID_GET_HANDLE(handle);
-
- /* Find the LCB based on the handle */
- tL2C_LCB* p_lcb = l2cu_find_lcb_by_handle(handle);
- if (p_lcb == nullptr) {
- log::warn("Received segment complete for unknown connection handle:{}", handle);
- osi_free(p_msg);
- return;
- }
-
- if (p_lcb->link_state != LST_CONNECTED) {
- log::info("Received segment complete for unconnected connection handle:{}:", handle);
- osi_free(p_msg);
- return;
- }
-
- /* Enqueue the buffer to the head of the transmit queue, and see */
- /* if we can transmit anything more. */
- list_prepend(p_lcb->link_xmit_data_q, p_msg);
-
- l2c_link_check_send_pkts(p_lcb, 0, NULL);
-}
-
tBTM_STATUS l2cu_ConnectAclForSecurity(const RawAddress& bd_addr) {
tL2C_LCB* p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_BR_EDR);
if (p_lcb && (p_lcb->link_state == LST_CONNECTED || p_lcb->link_state == LST_CONNECTING)) {
@@ -1222,7 +1181,7 @@ void l2cble_update_sec_act(const RawAddress& bd_addr, uint16_t sec_act) {
* Returns pointer to CCB or NULL
*
******************************************************************************/
-tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb) {
+static tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb) {
tL2C_CCB* p_serve_ccb = NULL;
tL2C_CCB* p_ccb;
@@ -1320,7 +1279,7 @@ tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb) {
* Returns pointer to buffer or NULL
*
******************************************************************************/
-BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb, tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
+static BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* p_lcb, tL2C_TX_COMPLETE_CB_INFO* p_cbi) {
tL2C_CCB* p_ccb;
BT_HDR* p_buf;
diff --git a/system/stack/l2cap/l2c_main.cc b/system/stack/l2cap/l2c_main.cc
index 9259283109..057b474f5b 100644
--- a/system/stack/l2cap/l2c_main.cc
+++ b/system/stack/l2cap/l2c_main.cc
@@ -35,14 +35,13 @@
#include "stack/include/bt_psm_types.h"
#include "stack/include/bt_types.h"
#include "stack/include/hcimsgs.h" // HCID_GET_
+#include "stack/include/l2cap_acl_interface.h"
#include "stack/include/l2cap_hci_link_interface.h"
#include "stack/include/l2cap_interface.h"
+#include "stack/include/l2cap_module.h"
#include "stack/include/l2cdefs.h"
#include "stack/l2cap/l2c_int.h"
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
using namespace bluetooth;
/******************************************************************************/
diff --git a/system/stack/l2cap/l2c_utils.cc b/system/stack/l2cap/l2c_utils.cc
index 6497bb1c37..0e923a559c 100644
--- a/system/stack/l2cap/l2c_utils.cc
+++ b/system/stack/l2cap/l2c_utils.cc
@@ -44,19 +44,16 @@
#include "stack/include/hci_error_code.h"
#include "stack/include/hcidefs.h"
#include "stack/include/l2cap_acl_interface.h"
+#include "stack/include/l2cap_controller_interface.h"
#include "stack/include/l2cap_hci_link_interface.h"
#include "stack/include/l2cap_interface.h"
+#include "stack/include/l2cap_security_interface.h"
#include "stack/include/l2cdefs.h"
#include "stack/l2cap/l2c_int.h"
#include "types/raw_address.h"
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
using namespace bluetooth;
-tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* p_lcb); // TODO Move
-
/* The offset in a buffer that L2CAP will use when building commands.
*/
#define L2CAP_SEND_CMD_OFFSET 0
@@ -305,7 +302,7 @@ bool l2c_is_cmd_rejected(uint8_t cmd_code, uint8_t signal_id, tL2C_LCB* p_lcb) {
* Returns Pointer to allocated packet or NULL if no resources
*
******************************************************************************/
-BT_HDR* l2cu_build_header(tL2C_LCB* p_lcb, uint16_t len, uint8_t cmd, uint8_t signal_id) {
+static BT_HDR* l2cu_build_header(tL2C_LCB* p_lcb, uint16_t len, uint8_t cmd, uint8_t signal_id) {
BT_HDR* p_buf = (BT_HDR*)osi_malloc(L2CAP_CMD_BUF_SIZE);
uint8_t* p;
@@ -348,7 +345,7 @@ BT_HDR* l2cu_build_header(tL2C_LCB* p_lcb, uint16_t len, uint8_t cmd, uint8_t si
* Returns void
*
******************************************************************************/
-void l2cu_adj_id(tL2C_LCB* p_lcb) {
+static void l2cu_adj_id(tL2C_LCB* p_lcb) {
if (p_lcb->signal_id == 0) {
p_lcb->signal_id++;
}
@@ -1466,6 +1463,11 @@ tL2C_CCB* l2cu_allocate_ccb(tL2C_LCB* p_lcb, uint16_t cid, bool is_eatt) {
alarm_free(p_ccb->l2c_ccb_timer);
p_ccb->l2c_ccb_timer = alarm_new("l2c.l2c_ccb_timer");
+#if (L2CAP_CONFORMANCE_TESTING == TRUE)
+ alarm_free(p_ccb->pts_config_delay_timer);
+ p_ccb->pts_config_delay_timer = alarm_new("pts.delay");
+#endif
+
l2c_link_adjust_chnl_allocation();
if (p_lcb != NULL) {
@@ -1575,6 +1577,11 @@ void l2cu_release_ccb(tL2C_CCB* p_ccb) {
alarm_free(p_ccb->l2c_ccb_timer);
p_ccb->l2c_ccb_timer = NULL;
+#if (L2CAP_CONFORMANCE_TESTING == TRUE)
+ alarm_free(p_ccb->pts_config_delay_timer);
+ p_ccb->pts_config_delay_timer = NULL;
+#endif
+
fixed_queue_free(p_ccb->xmit_hold_q, osi_free);
p_ccb->xmit_hold_q = NULL;
@@ -2199,28 +2206,6 @@ void l2cu_create_conn_br_edr(tL2C_LCB* p_lcb) {
/*******************************************************************************
*
- * Function l2cu_get_num_hi_priority
- *
- * Description Gets the number of high priority channels.
- *
- * Returns
- *
- ******************************************************************************/
-uint8_t l2cu_get_num_hi_priority(void) {
- uint8_t no_hi = 0;
- int xx;
- tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];
-
- for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
- if ((p_lcb->in_use) && (p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)) {
- no_hi++;
- }
- }
- return no_hi;
-}
-
-/*******************************************************************************
- *
* Function l2cu_create_conn_after_switch
*
* Description This continues a connection creation possibly after
diff --git a/system/stack/pan/pan_api.cc b/system/stack/pan/pan_api.cc
index 496a92050a..1fb209a17b 100644
--- a/system/stack/pan/pan_api.cc
+++ b/system/stack/pan/pan_api.cc
@@ -36,7 +36,7 @@
#include "bta/sys/bta_sys.h"
#include "internal_include/bt_target.h"
#include "main/shim/dumpsys.h"
-#include "os/log.h"
+#include "os/logging/log_adapter.h"
#include "osi/include/allocator.h"
#include "stack/include/bnep_api.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/pan/pan_main.cc b/system/stack/pan/pan_main.cc
index 88b433ed81..0b3cb55898 100644
--- a/system/stack/pan/pan_main.cc
+++ b/system/stack/pan/pan_main.cc
@@ -31,7 +31,6 @@
#include <cstdint>
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/bnep_api.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/stack/pan/pan_utils.cc b/system/stack/pan/pan_utils.cc
index eda89c4bed..eef9431004 100644
--- a/system/stack/pan/pan_utils.cc
+++ b/system/stack/pan/pan_utils.cc
@@ -30,7 +30,6 @@
#include <cstdint>
#include "internal_include/bt_target.h"
-#include "os/log.h"
#include "stack/include/bt_types.h"
#include "stack/include/bt_uuid16.h"
#include "stack/include/sdp_api.h"
diff --git a/system/stack/smp/smp_br_main.cc b/system/stack/smp/smp_br_main.cc
index 12ee374011..20e6459a02 100644
--- a/system/stack/smp/smp_br_main.cc
+++ b/system/stack/smp/smp_br_main.cc
@@ -20,7 +20,6 @@
#include <bluetooth/log.h>
-#include "os/log.h"
#include "smp_int.h"
#include "types/hci_role.h"
diff --git a/system/stack/smp/smp_main.cc b/system/stack/smp/smp_main.cc
index faaa2567cb..ead1d83028 100644
--- a/system/stack/smp/smp_main.cc
+++ b/system/stack/smp/smp_main.cc
@@ -20,7 +20,6 @@
#include <bluetooth/log.h>
-#include "os/log.h"
#include "smp_int.h"
#include "stack/include/btm_log_history.h"
diff --git a/system/stack/srvc/srvc_dis.cc b/system/stack/srvc/srvc_dis.cc
index 58f6befd11..38751c653c 100644
--- a/system/stack/srvc/srvc_dis.cc
+++ b/system/stack/srvc/srvc_dis.cc
@@ -23,7 +23,6 @@
#include "gatt_api.h"
#include "hardware/bt_gatt_types.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/osi.h"
#include "srvc_dis_int.h"
@@ -71,31 +70,6 @@ static tDIS_ATTR_MASK dis_uuid_to_attr(uint16_t uuid) {
}
/*******************************************************************************
- * dis_valid_handle_range
- *
- * validate a handle to be a DIS attribute handle or not.
- ******************************************************************************/
-bool dis_valid_handle_range(uint16_t /* handle */) { return false; }
-/*******************************************************************************
- * dis_write_attr_value
- *
- * Process write DIS attribute request.
- ******************************************************************************/
-uint8_t dis_write_attr_value(tGATT_WRITE_REQ* /* p_data */, tGATT_STATUS* p_status) {
- *p_status = GATT_WRITE_NOT_PERMIT;
- return SRVC_ACT_RSP;
-}
-/*******************************************************************************
- * DIS Attributes Database Server Request callback
- ******************************************************************************/
-uint8_t dis_read_attr_value(uint8_t /* clcb_idx */, uint16_t /* handle */,
- tGATT_VALUE* /* p_value */, bool /* is_long */,
- tGATT_STATUS* p_status) {
- *p_status = GATT_NOT_FOUND;
- return SRVC_ACT_RSP;
-}
-
-/*******************************************************************************
*
* Function dis_gatt_c_read_dis_value_cmpl
*
diff --git a/system/stack/srvc/srvc_dis_int.h b/system/stack/srvc/srvc_dis_int.h
index dae3071bc1..607162a102 100644
--- a/system/stack/srvc/srvc_dis_int.h
+++ b/system/stack/srvc/srvc_dis_int.h
@@ -45,11 +45,6 @@ typedef struct {
/* Global GATT data */
extern tDIS_CB dis_cb;
-bool dis_valid_handle_range(uint16_t handle);
-uint8_t dis_read_attr_value(uint8_t clcb_idx, uint16_t handle, tGATT_VALUE* p_value, bool is_long,
- tGATT_STATUS* p_status);
-uint8_t dis_write_attr_value(tGATT_WRITE_REQ* p_data, tGATT_STATUS* p_status);
-
void dis_c_cmpl_cback(tSRVC_CLCB* p_clcb, tGATTC_OPTYPE op, tGATT_STATUS status,
tGATT_CL_COMPLETE* p_data);
diff --git a/system/stack/srvc/srvc_eng.cc b/system/stack/srvc/srvc_eng.cc
index c1d877dd8e..92fb80cf71 100644
--- a/system/stack/srvc/srvc_eng.cc
+++ b/system/stack/srvc/srvc_eng.cc
@@ -27,11 +27,8 @@
#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"
-using base::StringPrintf;
using namespace bluetooth;
-static void srvc_eng_s_request_cback(tCONN_ID conn_id, uint32_t trans_id, tGATTS_REQ_TYPE type,
- tGATTS_DATA* p_data);
static void srvc_eng_connect_cback(tGATT_IF /* gatt_if */, const RawAddress& bda, tCONN_ID conn_id,
bool connected, tGATT_DISCONN_REASON reason,
tBT_TRANSPORT transport);
@@ -43,7 +40,7 @@ static tGATT_CBACK srvc_gatt_cback = {
.p_cmpl_cb = srvc_eng_c_cmpl_cback,
.p_disc_res_cb = nullptr,
.p_disc_cmpl_cb = nullptr,
- .p_req_cb = srvc_eng_s_request_cback,
+ .p_req_cb = nullptr,
.p_enc_cmpl_cb = nullptr,
.p_congestion_cb = nullptr,
.p_phy_update_cb = nullptr,
@@ -105,27 +102,6 @@ tSRVC_CLCB* srvc_eng_find_clcb_by_conn_id(tCONN_ID conn_id) {
}
/*******************************************************************************
*
- * Function srvc_eng_find_clcb_by_conn_id
- *
- * Description The function searches all LCBs with macthing connection ID.
- *
- * Returns Pointer to the found link conenction control block.
- *
- ******************************************************************************/
-static uint8_t srvc_eng_find_clcb_idx_by_conn_id(tCONN_ID conn_id) {
- uint8_t i_clcb;
- tSRVC_CLCB* p_clcb = NULL;
-
- for (i_clcb = 0, p_clcb = srvc_eng_cb.clcb; i_clcb < SRVC_MAX_APPS; i_clcb++, p_clcb++) {
- if (p_clcb->in_use && p_clcb->connected && p_clcb->conn_id == conn_id) {
- return i_clcb;
- }
- }
-
- return SRVC_MAX_APPS;
-}
-/*******************************************************************************
- *
* Function srvc_eng_clcb_alloc
*
* Description Allocate a GATT profile connection link control block
@@ -175,105 +151,6 @@ static bool srvc_eng_clcb_dealloc(tCONN_ID conn_id) {
}
return false;
}
-/*******************************************************************************
- * Service Engine Server Attributes Database Read/Read Blob Request process
- ******************************************************************************/
-static uint8_t srvc_eng_process_read_req(uint8_t clcb_idx, tGATT_READ_REQ* p_data,
- tGATTS_RSP* p_rsp, tGATT_STATUS* p_status) {
- tGATT_STATUS status = GATT_NOT_FOUND;
- uint8_t act = SRVC_ACT_RSP;
-
- if (p_data->is_long) {
- p_rsp->attr_value.offset = p_data->offset;
- }
-
- p_rsp->attr_value.handle = p_data->handle;
-
- if (dis_valid_handle_range(p_data->handle)) {
- act = dis_read_attr_value(clcb_idx, p_data->handle, &p_rsp->attr_value, p_data->is_long,
- p_status);
- } else {
- *p_status = status;
- }
- return act;
-}
-/*******************************************************************************
- * Service Engine Server Attributes Database write Request process
- ******************************************************************************/
-static uint8_t srvc_eng_process_write_req(uint8_t /* clcb_idx */, tGATT_WRITE_REQ* p_data,
- tGATTS_RSP* /* p_rsp */, tGATT_STATUS* p_status) {
- uint8_t act = SRVC_ACT_RSP;
-
- if (dis_valid_handle_range(p_data->handle)) {
- act = dis_write_attr_value(p_data, p_status);
- } else {
- *p_status = GATT_NOT_FOUND;
- }
-
- return act;
-}
-
-/*******************************************************************************
- *
- * Function srvc_eng_s_request_cback
- *
- * Description GATT DIS attribute access request callback.
- *
- * Returns void.
- *
- ******************************************************************************/
-static void srvc_eng_s_request_cback(tCONN_ID conn_id, uint32_t trans_id, tGATTS_REQ_TYPE type,
- tGATTS_DATA* p_data) {
- tGATT_STATUS status = GATT_INVALID_PDU;
- tGATTS_RSP rsp_msg;
- uint8_t act = SRVC_ACT_IGNORE;
- uint8_t clcb_idx = srvc_eng_find_clcb_idx_by_conn_id(conn_id);
- if (clcb_idx == SRVC_MAX_APPS) {
- log::error("Can't find clcb, id:{}", conn_id);
- return;
- }
-
- log::verbose("srvc_eng_s_request_cback : recv type (0x{:02x})", type);
-
- memset(&rsp_msg, 0, sizeof(tGATTS_RSP));
-
- srvc_eng_cb.clcb[clcb_idx].trans_id = trans_id;
-
- switch (type) {
- case GATTS_REQ_TYPE_READ_CHARACTERISTIC:
- case GATTS_REQ_TYPE_READ_DESCRIPTOR:
- act = srvc_eng_process_read_req(clcb_idx, &p_data->read_req, &rsp_msg, &status);
- break;
-
- case GATTS_REQ_TYPE_WRITE_CHARACTERISTIC:
- case GATTS_REQ_TYPE_WRITE_DESCRIPTOR:
- act = srvc_eng_process_write_req(clcb_idx, &p_data->write_req, &rsp_msg, &status);
- if (!p_data->write_req.need_rsp) {
- act = SRVC_ACT_IGNORE;
- }
- break;
-
- case GATTS_REQ_TYPE_WRITE_EXEC:
- log::verbose("Ignore GATT_REQ_EXEC_WRITE/WRITE_CMD");
- break;
-
- case GATTS_REQ_TYPE_MTU:
- log::verbose("Get MTU exchange new mtu size: {}", p_data->mtu);
- break;
-
- default:
- log::verbose("Unknown/unexpected LE GAP ATT request: 0x{:02x}", type);
- break;
- }
-
- srvc_eng_cb.clcb[clcb_idx].trans_id = 0;
-
- if (act == SRVC_ACT_RSP) {
- if (GATTS_SendRsp(conn_id, trans_id, status, &rsp_msg) != GATT_SUCCESS) {
- log::warn("Unable to send GATT server respond conn_id:{}", conn_id);
- }
- }
-}
/*******************************************************************************
*
@@ -381,7 +258,7 @@ void srvc_eng_release_channel(tCONN_ID conn_id) {
******************************************************************************/
tGATT_STATUS srvc_eng_init(void) {
if (srvc_eng_cb.enabled) {
- log::error("DIS already initialized");
+ log::verbose("DIS already initialized");
} else {
memset(&srvc_eng_cb, 0, sizeof(tSRVC_ENG_CB));
diff --git a/system/stack/test/a2dp/a2dp_sbc_unittest.cc b/system/stack/test/a2dp/a2dp_sbc_unittest.cc
index 950a6100dd..cde2795cfc 100644
--- a/system/stack/test/a2dp/a2dp_sbc_unittest.cc
+++ b/system/stack/test/a2dp/a2dp_sbc_unittest.cc
@@ -24,7 +24,6 @@
#include <string>
#include "common/time_util.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "stack/include/a2dp_sbc_decoder.h"
#include "stack/include/a2dp_sbc_encoder.h"
diff --git a/system/stack/test/a2dp/wav_reader.cc b/system/stack/test/a2dp/wav_reader.cc
index 0dddd30e9f..b692f17014 100644
--- a/system/stack/test/a2dp/wav_reader.cc
+++ b/system/stack/test/a2dp/wav_reader.cc
@@ -22,7 +22,6 @@
#include <iterator>
#include "os/files.h"
-#include "os/log.h"
namespace bluetooth {
namespace testing {
diff --git a/system/stack/test/btm_iso_test.cc b/system/stack/test/btm_iso_test.cc
index 50a4948b34..3cb550b04d 100644
--- a/system/stack/test/btm_iso_test.cc
+++ b/system/stack/test/btm_iso_test.cc
@@ -2085,6 +2085,84 @@ TEST_F(IsoManagerTest, SendIsoDataCigValid) {
}
}
+TEST_F(IsoManagerTest, SendReceiveIsoDataSequenceNumberCheck) {
+ IsoManager::GetInstance()->CreateCig(volatile_test_cig_create_cmpl_evt_.cig_id,
+ kDefaultCigParams);
+
+ bluetooth::hci::iso_manager::cis_establish_params params;
+ for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
+ params.conn_pairs.push_back({handle, 1});
+ }
+ IsoManager::GetInstance()->EstablishCis(params);
+
+ for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
+ bluetooth::hci::iso_manager::iso_data_path_params path_params = kDefaultIsoDataPathParams;
+ path_params.data_path_dir = bluetooth::hci::iso_manager::kIsoDataPathDirectionOut;
+ IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);
+
+ constexpr uint8_t data_len = 108;
+ uint16_t seq_num = 0xFFFF;
+
+ EXPECT_CALL(iso_interface_, HciSend)
+ .WillRepeatedly([handle, data_len, &seq_num](BT_HDR* p_msg) {
+ uint8_t* p = p_msg->data;
+ uint16_t msg_handle;
+ uint16_t iso_load_len;
+
+ ASSERT_NE(p_msg, nullptr);
+ ASSERT_EQ(p_msg->len,
+ data_len + ((p_msg->layer_specific & BT_ISO_HDR_CONTAINS_TS) ? 12 : 8));
+
+ // Verify packet internals
+ STREAM_TO_UINT16(msg_handle, p);
+ ASSERT_EQ(msg_handle, handle);
+
+ STREAM_TO_UINT16(iso_load_len, p);
+ ASSERT_EQ(iso_load_len,
+ data_len + ((p_msg->layer_specific & BT_ISO_HDR_CONTAINS_TS) ? 8 : 4));
+
+ if (p_msg->layer_specific & BT_ISO_HDR_CONTAINS_TS) {
+ STREAM_SKIP_UINT16(p); // skip ts LSB halfword
+ STREAM_SKIP_UINT16(p); // skip ts MSB halfword
+ }
+ // store the seq_nb
+ STREAM_TO_UINT16(seq_num, p);
+
+ uint16_t msg_data_len;
+ STREAM_TO_UINT16(msg_data_len, p);
+ ASSERT_EQ(msg_data_len, data_len);
+ })
+ .RetiresOnSaturation();
+
+ // Send Iso data and verify the sequence number
+ std::vector<uint8_t> data_vec(data_len, 0);
+ IsoManager::GetInstance()->SendIsoData(handle, data_vec.data(), data_vec.size());
+ IsoManager::GetInstance()->SendIsoData(handle, data_vec.data(), data_vec.size());
+ ASSERT_NE(0xFFFF, seq_num);
+
+ // Check the receiving iso packet
+ // EXPECT_CALL(*cig_callbacks_, OnCisEvent).Times(1);
+ EXPECT_CALL(*cig_callbacks_,
+ OnCisEvent(bluetooth::hci::iso_manager::kIsoEventCisDataAvailable, _))
+ .WillOnce([](uint8_t /*evt_code*/, void* event) {
+ bluetooth::hci::iso_manager::cis_data_evt* cis_data_evt =
+ static_cast<bluetooth::hci::iso_manager::cis_data_evt*>(event);
+ // Make sure no event lost is reported due to seq_nb being shared between two
+ // directions
+ ASSERT_EQ(cis_data_evt->evt_lost, 0);
+ });
+
+ std::vector<uint8_t> dummy_msg(18);
+ uint8_t* p = dummy_msg.data();
+ UINT16_TO_STREAM(p, BT_EVT_TO_BTU_HCI_ISO);
+ UINT16_TO_STREAM(p, 10); // .len
+ UINT16_TO_STREAM(p, 0); // .offset
+ UINT16_TO_STREAM(p, 0); // .layer_specific
+ UINT16_TO_STREAM(p, handle);
+ IsoManager::GetInstance()->HandleIsoData(dummy_msg.data());
+ }
+}
+
TEST_F(IsoManagerTest, SendIsoDataBigValid) {
IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id, kDefaultBigParams);
diff --git a/system/stack/test/gatt_connection_manager_test.cc b/system/stack/test/connection_manager_test.cc
index afe3fcba4e..cbb7b3ff35 100644
--- a/system/stack/test/gatt_connection_manager_test.cc
+++ b/system/stack/test/connection_manager_test.cc
@@ -1,3 +1,5 @@
+#include "stack/connection_manager/connection_manager.h"
+
#include <base/bind_helpers.h>
#include <base/functional/bind.h>
#include <base/functional/callback.h>
@@ -11,7 +13,6 @@
#include "osi/test/alarm_mock.h"
#include "security_device_record.h"
#include "stack/btm/neighbor_inquiry.h"
-#include "stack/gatt/connection_manager.h"
// TODO(b/369381361) Enfore -Wmissing-prototypes
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
diff --git a/system/stack/test/gatt/mock_gatt_utils_ref.cc b/system/stack/test/gatt/mock_gatt_utils_ref.cc
index f79db0ac3d..2f392b3e90 100644
--- a/system/stack/test/gatt/mock_gatt_utils_ref.cc
+++ b/system/stack/test/gatt/mock_gatt_utils_ref.cc
@@ -22,7 +22,7 @@
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
#pragma GCC diagnostic ignored "-Wunused-parameter"
-/** stack/gatt/connection_manager.cc */
+/** stack/connection_manager/connection_manager.cc */
namespace connection_manager {
bool background_connect_remove(uint8_t app_id, const RawAddress& address) { return false; }
bool direct_connect_remove(uint8_t app_id, const RawAddress& address, bool connection_timeout) {
diff --git a/system/stack/test/stack_avctp_test.cc b/system/stack/test/stack_avctp_test.cc
new file mode 100644
index 0000000000..17abac13c6
--- /dev/null
+++ b/system/stack/test/stack_avctp_test.cc
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2024 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 <bluetooth/log.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+
+#include "stack/include/avct_api.h"
+#include "stack/include/bt_psm_types.h"
+#include "test/fake/fake_osi.h"
+#include "test/mock/mock_stack_l2cap_interface.h"
+
+using ::testing::_;
+using ::testing::Args;
+using ::testing::DoAll;
+using ::testing::SaveArg;
+
+namespace {
+constexpr uint16_t kRemoteCid = 0x0123;
+const RawAddress kRawAddress = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
+} // namespace
+
+class StackAvctpTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ fake_osi_ = std::make_unique<::test::fake::FakeOsi>();
+ bluetooth::testing::stack::l2cap::set_interface(&mock_stack_l2cap_interface_);
+ EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_RegisterWithSecurity(_, _, _, _, _, _, _))
+ .WillRepeatedly([this](unsigned short psm, const tL2CAP_APPL_INFO& cb, bool /* c */,
+ tL2CAP_ERTM_INFO* /*d*/, unsigned short /* e */,
+ unsigned short /* f */, unsigned short /* g */) {
+ this->callback_map_.insert(std::make_tuple(psm, cb));
+ return psm;
+ });
+ EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_DisconnectReq(_)).WillRepeatedly([]() {
+ return true;
+ });
+ AVCT_Register();
+ // Make sure we have a callback for both PSMs
+ ASSERT_EQ(2U, callback_map_.size());
+ }
+
+ void TearDown() override {
+ EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_Deregister(BT_PSM_AVCTP));
+ EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_Deregister(BT_PSM_AVCTP_BROWSE));
+ AVCT_Deregister();
+ }
+
+ std::map<uint16_t, tL2CAP_APPL_INFO> callback_map_;
+ bluetooth::testing::stack::l2cap::Mock mock_stack_l2cap_interface_;
+ std::unique_ptr<test::fake::FakeOsi> fake_osi_;
+ int fd_{STDOUT_FILENO};
+};
+
+TEST_F(StackAvctpTest, AVCT_Dumpsys) { AVCT_Dumpsys(fd_); }
+
+TEST_F(StackAvctpTest, AVCT_CreateConn) {
+ EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_ConnectReqWithSecurity(_, _, _))
+ .WillRepeatedly([](unsigned short /* psm */, const RawAddress /* bd_addr */,
+ uint16_t /* sec_level */) { return 0x1234; });
+
+ uint8_t handle;
+ tAVCT_CC cc = {
+ .p_ctrl_cback = [](uint8_t /* handle */, uint8_t /* event */, uint16_t /* result */,
+ const RawAddress* /* peer_addr */) {},
+ .p_msg_cback = [](uint8_t /* handle */, uint8_t /* label */, uint8_t /* cr */,
+ BT_HDR* /* p_pkt */) {},
+ .pid = 0x1234,
+ .role = AVCT_ROLE_INITIATOR,
+ .control = 1,
+ };
+ ASSERT_EQ(AVCT_SUCCESS, AVCT_CreateConn(&handle, &cc, kRawAddress));
+ ASSERT_EQ(AVCT_SUCCESS, AVCT_RemoveConn(handle));
+}
+
+TEST_F(StackAvctpTest, AVCT_CreateBrowse) {
+ EXPECT_CALL(mock_stack_l2cap_interface_, L2CA_ConnectReqWithSecurity(_, _, _))
+ .WillRepeatedly([](unsigned short /* psm */, const RawAddress /* bd_addr */,
+ uint16_t /* sec_level */) { return 0x1234; });
+
+ uint8_t handle;
+ tAVCT_CC cc = {
+ .p_ctrl_cback = [](uint8_t /* handle */, uint8_t /* event */, uint16_t /* result */,
+ const RawAddress* /* peer_addr */) {},
+ .p_msg_cback = [](uint8_t /* handle */, uint8_t /* label */, uint8_t /* cr */,
+ BT_HDR* /* p_pkt */) {},
+ .pid = 0x1234,
+ .role = AVCT_ROLE_INITIATOR,
+ .control = 1,
+ };
+ ASSERT_EQ(AVCT_SUCCESS, AVCT_CreateConn(&handle, &cc, kRawAddress));
+ ASSERT_EQ(AVCT_SUCCESS, AVCT_CreateBrowse(handle, AVCT_ROLE_INITIATOR));
+
+ ASSERT_EQ(AVCT_SUCCESS, AVCT_RemoveBrowse(handle));
+ ASSERT_EQ(AVCT_SUCCESS, AVCT_RemoveConn(handle));
+}
+
+TEST_F(StackAvctpTest, AVCT_RemoteInitiatesControl) {
+ // AVCT Control
+ callback_map_[BT_PSM_AVCTP].pL2CA_ConnectInd_Cb(kRawAddress, kRemoteCid, BT_PSM_AVCTP, 0);
+ callback_map_[BT_PSM_AVCTP].pL2CA_ConnectCfm_Cb(kRemoteCid, tL2CAP_CONN::L2CAP_CONN_OK);
+}
+
+TEST_F(StackAvctpTest, AVCT_RemoteInitiatesBrowse) {
+ // AVCT Control
+ callback_map_[BT_PSM_AVCTP].pL2CA_ConnectInd_Cb(kRawAddress, kRemoteCid, BT_PSM_AVCTP, 0);
+ callback_map_[BT_PSM_AVCTP].pL2CA_ConnectCfm_Cb(kRemoteCid, tL2CAP_CONN::L2CAP_CONN_OK);
+
+ // AVCT Browse
+ callback_map_[BT_PSM_AVCTP_BROWSE].pL2CA_ConnectInd_Cb(kRawAddress, kRemoteCid,
+ BT_PSM_AVCTP_BROWSE, 0);
+ callback_map_[BT_PSM_AVCTP_BROWSE].pL2CA_ConnectCfm_Cb(kRemoteCid, tL2CAP_CONN::L2CAP_CONN_OK);
+
+ AVCT_Dumpsys(fd_);
+}
diff --git a/system/stack/test/stack_l2cap_test.cc b/system/stack/test/stack_l2cap_test.cc
index d2d19bf39e..ffe78055bc 100644
--- a/system/stack/test/stack_l2cap_test.cc
+++ b/system/stack/test/stack_l2cap_test.cc
@@ -287,7 +287,7 @@ TEST_F(StackL2capTest, bt_psm_text) {
{BT_PSM_UPNP, "BT_PSM_UPNP"},
{BT_PSM_AVCTP, "BT_PSM_AVCTP"},
{BT_PSM_AVDTP, "BT_PSM_AVDTP"},
- {BT_PSM_AVCTP_13, "BT_PSM_AVCTP_13"},
+ {BT_PSM_AVCTP_BROWSE, "BT_PSM_AVCTP_BROWSE"},
{BT_PSM_UDI_CP, "BT_PSM_UDI_CP"},
{BT_PSM_ATT, "BT_PSM_ATT"},
{BT_PSM_EATT, "BT_PSM_EATT"},
diff --git a/system/test/Android.bp b/system/test/Android.bp
index a78ed4e8ef..d4a1a767eb 100644
--- a/system/test/Android.bp
+++ b/system/test/Android.bp
@@ -484,6 +484,13 @@ filegroup {
}
filegroup {
+ name: "TestMockStackConnMgr",
+ srcs: [
+ "mock/mock_stack_connection_manager.cc",
+ ],
+}
+
+filegroup {
name: "TestMockStackEatt",
srcs: [
"mock/mock_stack_eatt*.cc",
diff --git a/system/test/common/jni_thread.cc b/system/test/common/jni_thread.cc
index 984b2337c1..db1520d36b 100644
--- a/system/test/common/jni_thread.cc
+++ b/system/test/common/jni_thread.cc
@@ -21,8 +21,6 @@
#include <map>
-#include "os/log.h"
-
// TODO(b/369381361) Enfore -Wmissing-prototypes
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
diff --git a/system/test/common/main_handler.cc b/system/test/common/main_handler.cc
index 8728ab1cd8..c6e792c4dc 100644
--- a/system/test/common/main_handler.cc
+++ b/system/test/common/main_handler.cc
@@ -27,7 +27,6 @@
#include "common/message_loop_thread.h"
#include "common/postable_context.h"
#include "include/hardware/bluetooth.h"
-#include "os/log.h"
// TODO(b/369381361) Enfore -Wmissing-prototypes
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
diff --git a/system/test/headless/adapter/adapter.cc b/system/test/headless/adapter/adapter.cc
index bbb3231047..cdf430d459 100644
--- a/system/test/headless/adapter/adapter.cc
+++ b/system/test/headless/adapter/adapter.cc
@@ -20,7 +20,6 @@
#include <bluetooth/log.h>
-#include "gd/os/log.h"
#include "test/headless/headless.h"
#include "test/headless/interface.h"
#include "test/headless/log.h"
diff --git a/system/test/headless/bt_stack_info.cc b/system/test/headless/bt_stack_info.cc
index ad00ba5c6b..300dbf62b7 100644
--- a/system/test/headless/bt_stack_info.cc
+++ b/system/test/headless/bt_stack_info.cc
@@ -21,7 +21,7 @@
#include "btif/include/btif_common.h" // do_in_jni_thread
#include "btif/include/btif_hh.h" // DumpsysHid
#include "main/shim/dumpsys.h"
-#include "stack/gatt/connection_manager.h"
+#include "stack/connection_manager/connection_manager.h"
#include "stack/include/main_thread.h"
#include "stack/include/pan_api.h" // PAN_Dumpsys
#include "test/headless/log.h"
diff --git a/system/test/headless/discovery/discovery.cc b/system/test/headless/discovery/discovery.cc
index 5244eb893a..34c295188b 100644
--- a/system/test/headless/discovery/discovery.cc
+++ b/system/test/headless/discovery/discovery.cc
@@ -21,7 +21,6 @@
#include <future>
#include "btif/include/btif_api.h"
-#include "os/log.h" // android log only
#include "stack/include/sdp_api.h"
#include "test/headless/bt_property.h"
#include "test/headless/get_options.h"
diff --git a/system/test/headless/get_options.cc b/system/test/headless/get_options.cc
index 3ad9fd48e5..fcab08d45d 100644
--- a/system/test/headless/get_options.cc
+++ b/system/test/headless/get_options.cc
@@ -23,7 +23,6 @@
#include <sstream>
#include <string>
-#include "os/log.h"
#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"
diff --git a/system/test/headless/headless.cc b/system/test/headless/headless.cc
index ebfcb041ec..5f0d820c7a 100644
--- a/system/test/headless/headless.cc
+++ b/system/test/headless/headless.cc
@@ -25,7 +25,6 @@
#include <map>
#include <memory>
-#include "gd/os/log.h"
#include "include/hardware/bluetooth.h"
#include "test/headless/bt_stack_info.h"
#include "test/headless/interface.h"
diff --git a/system/test/headless/interface.h b/system/test/headless/interface.h
index f06df13a4c..11c314c8b7 100644
--- a/system/test/headless/interface.h
+++ b/system/test/headless/interface.h
@@ -21,7 +21,6 @@
#include <deque>
#include <string>
-#include "gd/os/log.h"
#include "include/hardware/bluetooth.h"
#include "macros.h"
#include "test/headless/log.h"
diff --git a/system/test/headless/log.cc b/system/test/headless/log.cc
index 4714b98c2d..729db46475 100644
--- a/system/test/headless/log.cc
+++ b/system/test/headless/log.cc
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#include "os/log.h"
-
#include <chrono>
#include <ctime>
#include <string>
diff --git a/system/test/headless/main.cc b/system/test/headless/main.cc
index feba9c1909..313b0f1e71 100644
--- a/system/test/headless/main.cc
+++ b/system/test/headless/main.cc
@@ -25,7 +25,6 @@
#include <iostream>
#include <unordered_map>
-#include "os/log.h" // android log only
#include "test/headless/adapter/adapter.h"
#include "test/headless/connect/connect.h"
#include "test/headless/discovery/discovery.h"
diff --git a/system/test/headless/nop/nop.cc b/system/test/headless/nop/nop.cc
index fcae19aa25..5383953608 100644
--- a/system/test/headless/nop/nop.cc
+++ b/system/test/headless/nop/nop.cc
@@ -20,7 +20,6 @@
#include <future>
-#include "os/log.h" // android log only
#include "stack/include/sdp_api.h"
#include "test/headless/get_options.h"
#include "test/headless/headless.h"
diff --git a/system/test/headless/property.cc b/system/test/headless/property.cc
index 65373f82f9..fe6e21f1ed 100644
--- a/system/test/headless/property.cc
+++ b/system/test/headless/property.cc
@@ -20,7 +20,6 @@
#include <map>
-#include "gd/os/log.h"
#include "include/hardware/bluetooth.h"
#include "test/headless/log.h"
diff --git a/system/test/headless/read/read.cc b/system/test/headless/read/read.cc
index 08cf26d8fd..51e29448ac 100644
--- a/system/test/headless/read/read.cc
+++ b/system/test/headless/read/read.cc
@@ -18,7 +18,6 @@
#include "test/headless/read/read.h"
-#include "os/log.h" // android log only
#include "test/headless/get_options.h"
#include "test/headless/headless.h"
#include "test/headless/read/name.h"
diff --git a/system/test/headless/scan/scan.cc b/system/test/headless/scan/scan.cc
index d72b52236a..58c7bc9bcf 100644
--- a/system/test/headless/scan/scan.cc
+++ b/system/test/headless/scan/scan.cc
@@ -20,7 +20,6 @@
#include <bluetooth/log.h>
-#include "os/log.h"
#include "test/headless/get_options.h"
#include "test/headless/headless.h"
#include "test/headless/interface.h"
diff --git a/system/test/headless/text.cc b/system/test/headless/text.cc
index dc9303b982..fefc47780d 100644
--- a/system/test/headless/text.cc
+++ b/system/test/headless/text.cc
@@ -22,7 +22,6 @@
#include "include/hardware/bluetooth.h"
#include "macros.h"
-#include "os/log.h"
std::string bt_conn_direction_text(const bt_conn_direction_t& direction) {
switch (direction) {
diff --git a/system/test/mock/mock_bta_av_api.h b/system/test/mock/mock_bta_av_api.h
index f6319691c0..31fd804f67 100644
--- a/system/test/mock/mock_bta_av_api.h
+++ b/system/test/mock/mock_bta_av_api.h
@@ -33,7 +33,6 @@
// may need attention to prune from (or add to ) the inclusion set.
#include "bta/av/bta_av_int.h"
#include "btif/include/btif_av.h"
-#include "os/log.h"
#include "osi/include/allocator.h"
#include "osi/include/compat.h"
#include "stack/include/bt_hdr.h"
diff --git a/system/test/mock/mock_stack_avct_api.cc b/system/test/mock/mock_stack_avct_api.cc
index 42dae21043..2e88b66e84 100644
--- a/system/test/mock/mock_stack_avct_api.cc
+++ b/system/test/mock/mock_stack_avct_api.cc
@@ -24,7 +24,7 @@
#include "test/common/mock_functions.h"
#include "types/raw_address.h"
-uint16_t AVCT_CreateBrowse(uint8_t /* handle */, uint8_t /* role */) {
+uint16_t AVCT_CreateBrowse(uint8_t /* handle */, tAVCT_ROLE /* role */) {
inc_func_call_count(__func__);
return 0;
}
@@ -56,3 +56,4 @@ uint16_t AVCT_RemoveConn(uint8_t /* handle */) {
}
void AVCT_Deregister(void) { inc_func_call_count(__func__); }
void AVCT_Register() { inc_func_call_count(__func__); }
+void AVCT_Dumpsys(int /* fd */) { inc_func_call_count(__func__); }
diff --git a/system/test/mock/mock_stack_avrc_api.cc b/system/test/mock/mock_stack_avrc_api.cc
index 5409f75345..655690c7ec 100644
--- a/system/test/mock/mock_stack_avrc_api.cc
+++ b/system/test/mock/mock_stack_avrc_api.cc
@@ -25,9 +25,6 @@
#include "test/common/mock_functions.h"
#include "types/raw_address.h"
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
bool avrcp_absolute_volume_is_enabled() {
inc_func_call_count(__func__);
return true;
@@ -58,7 +55,7 @@ uint16_t AVRC_Open(uint8_t* /* p_handle */, tAVRC_CONN_CB* /* p_ccb */,
inc_func_call_count(__func__);
return 0;
}
-uint16_t AVRC_OpenBrowse(uint8_t /* handle */, uint8_t /* conn_role */) {
+uint16_t AVRC_OpenBrowse(uint8_t /* handle */, tAVCT_ROLE /* conn_role */) {
inc_func_call_count(__func__);
return 0;
}
@@ -79,7 +76,6 @@ uint16_t AVRC_PassRsp(uint8_t /* handle */, uint8_t /* label */, tAVRC_MSG_PASS*
return 0;
}
void avrc_flush_cmd_q(uint8_t /* handle */) { inc_func_call_count(__func__); }
-void avrc_process_timeout(void* /* data */) { inc_func_call_count(__func__); }
void avrc_send_next_vendor_cmd(uint8_t /* handle */) { inc_func_call_count(__func__); }
void avrc_start_cmd_timer(uint8_t /* handle */, uint8_t /* label */, uint8_t /* msg_mask */) {
inc_func_call_count(__func__);
diff --git a/system/test/mock/mock_stack_avrc_bld_tg.cc b/system/test/mock/mock_stack_avrc_bld_tg.cc
index 6a1f126edd..7ff5e8fc26 100644
--- a/system/test/mock/mock_stack_avrc_bld_tg.cc
+++ b/system/test/mock/mock_stack_avrc_bld_tg.cc
@@ -24,15 +24,8 @@
#include "stack/include/bt_hdr.h"
#include "test/common/mock_functions.h"
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
tAVRC_STS AVRC_BldResponse(uint8_t /* handle */, tAVRC_RESPONSE* /* p_rsp */,
BT_HDR** /* pp_pkt */) {
inc_func_call_count(__func__);
return 0;
}
-tAVRC_STS avrc_bld_group_navigation_rsp(uint16_t /* navi_id */, BT_HDR* /* p_pkt */) {
- inc_func_call_count(__func__);
- return 0;
-}
diff --git a/system/test/mock/mock_stack_avrc_pars.ct.cc b/system/test/mock/mock_stack_avrc_pars.ct.cc
index 511231e11d..193f2f21b5 100644
--- a/system/test/mock/mock_stack_avrc_pars.ct.cc
+++ b/system/test/mock/mock_stack_avrc_pars.ct.cc
@@ -23,9 +23,6 @@
#include "avrc_defs.h"
#include "test/common/mock_functions.h"
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
tAVRC_STS AVRC_Ctrl_ParsResponse(tAVRC_MSG* /* p_msg */, tAVRC_RESPONSE* /* p_result */,
uint8_t* /* p_buf */, uint16_t* /* buf_len */) {
inc_func_call_count(__func__);
@@ -36,8 +33,3 @@ tAVRC_STS AVRC_ParsResponse(tAVRC_MSG* /* p_msg */, tAVRC_RESPONSE* /* p_result
inc_func_call_count(__func__);
return 0;
}
-tAVRC_STS avrc_parse_notification_rsp(uint8_t* /* p_stream */, uint16_t /* len */,
- tAVRC_REG_NOTIF_RSP* /* p_rsp */) {
- inc_func_call_count(__func__);
- return 0;
-}
diff --git a/system/test/mock/mock_stack_gatt_connection_manager.cc b/system/test/mock/mock_stack_connection_manager.cc
index f0f33dddb5..97cd160854 100644
--- a/system/test/mock/mock_stack_gatt_connection_manager.cc
+++ b/system/test/mock/mock_stack_connection_manager.cc
@@ -21,12 +21,18 @@
#include <set>
-#include "stack/gatt/connection_manager.h"
+#include "stack/connection_manager/connection_manager.h"
#include "test/common/mock_functions.h"
#include "types/raw_address.h"
using namespace connection_manager;
+bool connection_manager::background_connect_targeted_announcement_add(
+ tAPP_ID /* app_id */, const RawAddress& /* address */) {
+ inc_func_call_count(__func__);
+ return false;
+}
+
bool connection_manager::background_connect_add(uint8_t /* app_id */,
const RawAddress& /* address */) {
inc_func_call_count(__func__);
diff --git a/system/test/mock/mock_stack_l2cap_api.cc b/system/test/mock/mock_stack_l2cap_api.cc
index c360878a6b..b8f3f4e227 100644
--- a/system/test/mock/mock_stack_l2cap_api.cc
+++ b/system/test/mock/mock_stack_l2cap_api.cc
@@ -37,7 +37,6 @@ namespace mock {
namespace stack_l2cap_api {
// Function state capture and return values, if needed
-struct l2c_get_transport_from_fixed_cid l2c_get_transport_from_fixed_cid;
struct L2CA_RegisterWithSecurity L2CA_RegisterWithSecurity;
struct L2CA_Register L2CA_Register;
struct L2CA_Deregister L2CA_Deregister;
@@ -82,10 +81,6 @@ struct L2CA_LeCreditThreshold L2CA_LeCreditThreshold;
} // namespace test
// Mocked functions, if any
-tBT_TRANSPORT l2c_get_transport_from_fixed_cid(uint16_t fixed_cid) {
- inc_func_call_count(__func__);
- return test::mock::stack_l2cap_api::l2c_get_transport_from_fixed_cid(fixed_cid);
-}
uint16_t L2CA_RegisterWithSecurity(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
uint16_t my_mtu, uint16_t required_remote_mtu,
diff --git a/system/test/mock/mock_stack_l2cap_api.h b/system/test/mock/mock_stack_l2cap_api.h
index c2d162afd2..40d746ecd3 100644
--- a/system/test/mock/mock_stack_l2cap_api.h
+++ b/system/test/mock/mock_stack_l2cap_api.h
@@ -39,17 +39,6 @@
namespace test {
namespace mock {
namespace stack_l2cap_api {
-
-// Shared state between mocked functions and tests
-// Name: l2c_get_transport_from_fixed_cid
-// Params: uint16_t fixed_cid
-// Returns: tBT_TRANSPORT
-struct l2c_get_transport_from_fixed_cid {
- std::function<tBT_TRANSPORT(uint16_t fixed_cid)> body{
- [](uint16_t /* fixed_cid */) { return BT_TRANSPORT_AUTO; }};
- tBT_TRANSPORT operator()(uint16_t fixed_cid) { return body(fixed_cid); }
-};
-extern struct l2c_get_transport_from_fixed_cid l2c_get_transport_from_fixed_cid;
// Name: L2CA_RegisterWithSecurity
// Params: uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, bool enable_snoop,
// tL2CAP_ERTM_INFO* p_ertm_info, uint16_t my_mtu, uint16_t required_remote_mtu,
diff --git a/system/test/mock/mock_stack_l2cap_ble.cc b/system/test/mock/mock_stack_l2cap_ble.cc
index ee62576516..7dcd2f6bf0 100644
--- a/system/test/mock/mock_stack_l2cap_ble.cc
+++ b/system/test/mock/mock_stack_l2cap_ble.cc
@@ -58,7 +58,6 @@ struct l2cble_credit_based_conn_req l2cble_credit_based_conn_req;
struct l2cble_credit_based_conn_res l2cble_credit_based_conn_res;
struct l2cble_send_flow_control_credit l2cble_send_flow_control_credit;
struct l2cble_send_peer_disc_req l2cble_send_peer_disc_req;
-struct l2cble_sec_comp l2cble_sec_comp;
struct l2ble_sec_access_req l2ble_sec_access_req;
struct L2CA_AdjustConnectionIntervals L2CA_AdjustConnectionIntervals;
struct L2CA_SetEcosystemBaseInterval L2CA_SetEcosystemBaseInterval;
@@ -158,11 +157,6 @@ void l2cble_send_peer_disc_req(tL2C_CCB* p_ccb) {
inc_func_call_count(__func__);
test::mock::stack_l2cap_ble::l2cble_send_peer_disc_req(p_ccb);
}
-void l2cble_sec_comp(const RawAddress* bda, tBT_TRANSPORT transport, void* p_ref_data,
- tBTM_STATUS status) {
- inc_func_call_count(__func__);
- test::mock::stack_l2cap_ble::l2cble_sec_comp(bda, transport, p_ref_data, status);
-}
tL2CAP_LE_RESULT_CODE l2ble_sec_access_req(const RawAddress& bd_addr, uint16_t psm,
bool is_originator, tBTM_SEC_CALLBACK* p_callback,
void* p_ref_data) {
diff --git a/system/test/mock/mock_stack_l2cap_ble.h b/system/test/mock/mock_stack_l2cap_ble.h
index 6f13fed735..c5c3e45a1d 100644
--- a/system/test/mock/mock_stack_l2cap_ble.h
+++ b/system/test/mock/mock_stack_l2cap_ble.h
@@ -227,20 +227,6 @@ struct l2cble_send_peer_disc_req {
void operator()(tL2C_CCB* p_ccb) { body(p_ccb); }
};
extern struct l2cble_send_peer_disc_req l2cble_send_peer_disc_req;
-// Name: l2cble_sec_comp
-// Params: const RawAddress* bda, tBT_TRANSPORT transport, void* p_ref_data,
-// tBTM_STATUS status Returns: void
-struct l2cble_sec_comp {
- std::function<void(const RawAddress* bda, tBT_TRANSPORT transport, void* p_ref_data,
- tBTM_STATUS status)>
- body{[](const RawAddress* /* bda */, tBT_TRANSPORT /* transport */,
- void* /* p_ref_data */, tBTM_STATUS /* status */) {}};
- void operator()(const RawAddress* bda, tBT_TRANSPORT transport, void* p_ref_data,
- tBTM_STATUS status) {
- body(bda, transport, p_ref_data, status);
- }
-};
-extern struct l2cble_sec_comp l2cble_sec_comp;
// Name: l2ble_sec_access_req
// Params: const RawAddress& bd_addr, uint16_t psm, bool is_originator,
// tL2CAP_SEC_CBACK* p_callback, void* p_ref_data Returns: tL2CAP_LE_RESULT_CODE
diff --git a/system/test/mock/mock_stack_l2cap_link.cc b/system/test/mock/mock_stack_l2cap_link.cc
index c0dea8c1fc..0c520ee594 100644
--- a/system/test/mock/mock_stack_l2cap_link.cc
+++ b/system/test/mock/mock_stack_l2cap_link.cc
@@ -22,17 +22,14 @@
#include "stack/include/bt_hdr.h"
#include "stack/include/btm_status.h"
+#include "stack/include/l2cap_acl_interface.h"
+#include "stack/include/l2cap_controller_interface.h"
+#include "stack/include/l2cap_hci_link_interface.h"
+#include "stack/include/l2cap_security_interface.h"
#include "stack/l2cap/l2c_int.h"
#include "test/common/mock_functions.h"
#include "types/raw_address.h"
-// TODO(b/369381361) Enfore -Wmissing-prototypes
-#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-
-BT_HDR* l2cu_get_next_buffer_to_send(tL2C_LCB* /* p_lcb */) {
- inc_func_call_count(__func__);
- return nullptr;
-}
bool l2c_link_hci_disc_comp(uint16_t /* handle */, tHCI_REASON /* reason */) {
inc_func_call_count(__func__);
return false;
@@ -41,10 +38,6 @@ tBTM_STATUS l2cu_ConnectAclForSecurity(const RawAddress& /* bd_addr */) {
inc_func_call_count(__func__);
return tBTM_STATUS::BTM_SUCCESS;
}
-tL2C_CCB* l2cu_get_next_channel_in_rr(tL2C_LCB* /* p_lcb */) {
- inc_func_call_count(__func__);
- return nullptr;
-}
void l2c_OnHciModeChangeSendPendingPackets(RawAddress /* remote */) {
inc_func_call_count(__func__);
}
@@ -64,12 +57,11 @@ void l2c_link_role_changed(const RawAddress* /* bd_addr */, tHCI_ROLE /* new_rol
tHCI_STATUS /* hci_status */) {
inc_func_call_count(__func__);
}
-void l2c_link_sec_comp(const RawAddress* /* p_bda */, tBT_TRANSPORT /* transport */,
- void* /* p_ref_data */, uint8_t /* status */) {
+void l2c_link_sec_comp(const RawAddress /* bda */, tBT_TRANSPORT /* transport */,
+ void* /* p_ref_data */, tBTM_STATUS /* status */) {
inc_func_call_count(__func__);
}
-void l2c_link_segments_xmitted(BT_HDR* /* p_msg */) { inc_func_call_count(__func__); }
void l2c_link_timeout(tL2C_LCB* /* p_lcb */) { inc_func_call_count(__func__); }
void l2c_packets_completed(uint16_t /* handle */, uint16_t /* num_sent */) {
inc_func_call_count(__func__);
diff --git a/system/test/mock/mock_stack_l2cap_utils.cc b/system/test/mock/mock_stack_l2cap_utils.cc
index accdc72881..f485c111e4 100644
--- a/system/test/mock/mock_stack_l2cap_utils.cc
+++ b/system/test/mock/mock_stack_l2cap_utils.cc
@@ -29,11 +29,6 @@
// TODO(b/369381361) Enfore -Wmissing-prototypes
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
-BT_HDR* l2cu_build_header(tL2C_LCB* /* p_lcb */, uint16_t /* len */, uint8_t /* cmd */,
- uint8_t /* signal_id */) {
- inc_func_call_count(__func__);
- return nullptr;
-}
bool l2c_is_cmd_rejected(uint8_t /* cmd_code */, uint8_t /* signal_id */, tL2C_LCB* /* p_lcb */) {
inc_func_call_count(__func__);
return false;
@@ -113,15 +108,10 @@ tL2C_RCB* l2cu_find_rcb_by_psm(uint16_t /* psm */) {
inc_func_call_count(__func__);
return nullptr;
}
-uint8_t l2cu_get_num_hi_priority(void) {
- inc_func_call_count(__func__);
- return 0;
-}
uint8_t l2cu_process_peer_cfg_req(tL2C_CCB* /* p_ccb */, tL2CAP_CFG_INFO* /* p_cfg */) {
inc_func_call_count(__func__);
return 0;
}
-void l2cu_adj_id(tL2C_LCB* /* p_lcb */) { inc_func_call_count(__func__); }
void l2cu_adjust_out_mps(tL2C_CCB* /* p_ccb */) { inc_func_call_count(__func__); }
void l2cu_change_pri_ccb(tL2C_CCB* /* p_ccb */, tL2CAP_CHNL_PRIORITY /* priority */) {
inc_func_call_count(__func__);
diff --git a/system/test/mock/mock_stack_srvc_dis.cc b/system/test/mock/mock_stack_srvc_dis.cc
index abd467c3a9..fc301ea0a1 100644
--- a/system/test/mock/mock_stack_srvc_dis.cc
+++ b/system/test/mock/mock_stack_srvc_dis.cc
@@ -38,20 +38,6 @@ bool dis_gatt_c_read_dis_req(uint16_t /* conn_id */) {
inc_func_call_count(__func__);
return false;
}
-bool dis_valid_handle_range(uint16_t /* handle */) {
- inc_func_call_count(__func__);
- return false;
-}
-uint8_t dis_read_attr_value(uint8_t /* clcb_idx */, uint16_t /* handle */,
- tGATT_VALUE* /* p_value */, bool /* is_long */,
- tGATT_STATUS* /* p_status */) {
- inc_func_call_count(__func__);
- return 0;
-}
-uint8_t dis_write_attr_value(tGATT_WRITE_REQ* /* p_data */, tGATT_STATUS* /* p_status */) {
- inc_func_call_count(__func__);
- return 0;
-}
void dis_c_cmpl_cback(tSRVC_CLCB* /* p_clcb */, tGATTC_OPTYPE /* op */, tGATT_STATUS /* status */,
tGATT_CL_COMPLETE* /* p_data */) {
inc_func_call_count(__func__);
diff --git a/system/test/stub/osi.cc b/system/test/stub/osi.cc
index fcfa858a91..17accc1794 100644
--- a/system/test/stub/osi.cc
+++ b/system/test/stub/osi.cc
@@ -20,6 +20,7 @@
#include "osi/include/osi.h"
+#include <bluetooth/log.h>
#include <sys/socket.h>
#include <list>
@@ -335,24 +336,70 @@ alarm_t* alarm_new_periodic(const char* name) {
inc_func_call_count(__func__);
return nullptr;
}
+
+// Callback to last set alarm
struct fake_osi_alarm_set_on_mloop fake_osi_alarm_set_on_mloop_;
+
+// Vector of previous osi alarms. Keep it for proper handling alarm_is_scheduler function
+static std::vector<struct fake_osi_alarm_set_on_mloop> previous_fake_osi_alarms_;
+
bool alarm_is_scheduled(const alarm_t* alarm) {
inc_func_call_count(__func__);
- return fake_osi_alarm_set_on_mloop_.cb != nullptr;
+
+ auto iter =
+ find_if(previous_fake_osi_alarms_.begin(), previous_fake_osi_alarms_.end(),
+ [alarm](auto const& a) {
+ bluetooth::log::debug("iter: {} == {} ?", fmt::ptr(a.alarm), fmt::ptr(alarm));
+ return a.alarm == alarm;
+ });
+ if (iter != previous_fake_osi_alarms_.end()) {
+ return true;
+ }
+
+ bluetooth::log::debug(" {} == {} ?", fmt::ptr(fake_osi_alarm_set_on_mloop_.alarm),
+ fmt::ptr(alarm));
+
+ return fake_osi_alarm_set_on_mloop_.alarm == alarm;
}
uint64_t alarm_get_remaining_ms(const alarm_t* alarm) {
inc_func_call_count(__func__);
return 0;
}
+
+static void fake_osi_alarm_clear(alarm_t* alarm) {
+ if (alarm != nullptr) {
+ auto iter = find_if(previous_fake_osi_alarms_.begin(), previous_fake_osi_alarms_.end(),
+ [alarm](auto const& a) { return a.alarm == alarm; });
+ if (iter != previous_fake_osi_alarms_.end()) {
+ bluetooth::log::debug(" clearing alarm {} ", fmt::ptr(iter->alarm));
+ previous_fake_osi_alarms_.erase(iter);
+ return;
+ }
+ }
+
+ if (fake_osi_alarm_set_on_mloop_.alarm == alarm || alarm == nullptr) {
+ bluetooth::log::debug(" clearing alarm {} ", fmt::ptr(alarm));
+ fake_osi_alarm_set_on_mloop_.alarm = nullptr;
+ fake_osi_alarm_set_on_mloop_.interval_ms = 0;
+ fake_osi_alarm_set_on_mloop_.cb = nullptr;
+ fake_osi_alarm_set_on_mloop_.data = nullptr;
+ }
+}
+
void alarm_cancel(alarm_t* alarm) {
inc_func_call_count(__func__);
- fake_osi_alarm_set_on_mloop_.interval_ms = 0;
- fake_osi_alarm_set_on_mloop_.cb = nullptr;
- fake_osi_alarm_set_on_mloop_.data = nullptr;
+ fake_osi_alarm_clear(alarm);
+}
+
+void alarm_cleanup(void) {
+ previous_fake_osi_alarms_.clear();
+ fake_osi_alarm_clear(nullptr);
+
+ inc_func_call_count(__func__);
}
-void alarm_cleanup(void) { inc_func_call_count(__func__); }
void alarm_debug_dump(int fd) { inc_func_call_count(__func__); }
void alarm_free(alarm_t* alarm) {
+ fake_osi_alarm_clear(alarm);
uint8_t* ptr = (uint8_t*)alarm;
delete[] ptr;
inc_func_call_count(__func__);
@@ -363,6 +410,14 @@ void alarm_set(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void*
void alarm_set_on_mloop(alarm_t* alarm, uint64_t interval_ms, alarm_callback_t cb, void* data) {
inc_func_call_count(__func__);
+
+ if (fake_osi_alarm_set_on_mloop_.alarm != nullptr) {
+ bluetooth::log::info("Queuing alarm {}", fmt::ptr(fake_osi_alarm_set_on_mloop_.alarm));
+ previous_fake_osi_alarms_.push_back(fake_osi_alarm_set_on_mloop_);
+ }
+
+ bluetooth::log::info("Adding alarm {}", fmt::ptr(alarm));
+ fake_osi_alarm_set_on_mloop_.alarm = alarm;
fake_osi_alarm_set_on_mloop_.interval_ms = interval_ms;
fake_osi_alarm_set_on_mloop_.cb = cb;
fake_osi_alarm_set_on_mloop_.data = data;
diff --git a/system/udrv/ulinux/uipc.cc b/system/udrv/ulinux/uipc.cc
index 464e02b7f1..d0d7de0fbb 100644
--- a/system/udrv/ulinux/uipc.cc
+++ b/system/udrv/ulinux/uipc.cc
@@ -44,7 +44,6 @@
#include <cerrno>
#include <mutex>
-#include "os/log.h"
#include "osi/include/osi.h"
#include "osi/include/socket_utils/sockets.h"
diff --git a/tools/rootcanal/packets/hci_packets.pdl b/tools/rootcanal/packets/hci_packets.pdl
index ec34b4da0f..db7c51d294 100644
--- a/tools/rootcanal/packets/hci_packets.pdl
+++ b/tools/rootcanal/packets/hci_packets.pdl
@@ -749,6 +749,7 @@ enum EventCode : 8 {
REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION = 0x3D,
LE_META_EVENT = 0x3e,
NUMBER_OF_COMPLETED_DATA_BLOCKS = 0x48,
+ AUTHENTICATED_PAYLOAD_TIMEOUT_EXPIRED = 0x57,
ENCRYPTION_CHANGE_V2 = 0x59,
VENDOR_SPECIFIC = 0xFF,
}
@@ -5134,6 +5135,11 @@ packet NumberOfCompletedDataBlocks : Event (event_code = NUMBER_OF_COMPLETED_DAT
_payload_, // placeholder (unimplemented)
}
+packet AuthenticatedPayloadTimeoutExpired : Event (event_code = AUTHENTICATED_PAYLOAD_TIMEOUT_EXPIRED) {
+ connection_handle : 12,
+ _reserved_ : 4,
+}
+
// LE Events
packet LeConnectionComplete : LeMetaEvent (subevent_code = CONNECTION_COMPLETE) {
status : ErrorCode,