From 6fea8165e4ffa2e1acc60b2eb18a17eb140c3078 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Thu, 9 May 2024 20:49:46 +0800 Subject: [PATCH 0001/1446] [HFP Client] Check peer HF indicator supported flag Bug: 339610138 Test: atest avatar Flag: EXEMPT change only for hf cilent BIEV issue fix, no extra business logic. Change-Id: Ie6ce08e7ffb6f2cf08e7732e733b1cb2155a920f --- system/bta/hf_client/bta_hf_client_at.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/bta/hf_client/bta_hf_client_at.cc b/system/bta/hf_client/bta_hf_client_at.cc index f8730ca6680..823316f1d8c 100644 --- a/system/bta/hf_client/bta_hf_client_at.cc +++ b/system/bta/hf_client/bta_hf_client_at.cc @@ -1913,7 +1913,7 @@ void bta_hf_client_send_at_biev(tBTA_HF_CLIENT_CB* client_cb, int indicator_id, char buf[32]; tBTA_HF_CLIENT_AT_CMD cmd = BTA_HF_CLIENT_AT_BIEV; - if ((client_cb->peer_features & BTA_HF_CLIENT_FEAT_HF_IND) == 0) { + if ((client_cb->peer_features & BTA_HF_CLIENT_PEER_HF_IND) == 0) { log::error("peer does not support HF Indicators"); return; } -- GitLab From 6e5bafd582484790fad61c0c6409a0b57bdcc788 Mon Sep 17 00:00:00 2001 From: Hsin-chen Chuang Date: Wed, 5 Jun 2024 14:34:32 +0800 Subject: [PATCH 0002/1446] floss: Box the OobData structure in BaseCallbacks OobData (321 bytes) is much larger than the other enum (2nd large is ~40 btyes), which is wasting many memory space. Bug: 343315863 Tag: #floss Test: mmm packages/modules/Bluetooth Flag: EXEMPT, Floss-only changes Change-Id: I004f0f616d8bf975c8514bedf0308b6267c60af2 --- system/gd/rust/topshim/src/btif.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/gd/rust/topshim/src/btif.rs b/system/gd/rust/topshim/src/btif.rs index edbd5394b0c..aadf54d45bb 100644 --- a/system/gd/rust/topshim/src/btif.rs +++ b/system/gd/rust/topshim/src/btif.rs @@ -1053,7 +1053,7 @@ pub enum BaseCallbacks { // link_quality_report_cb // switch_buffer_size_cb // switch_codec_cb - GenerateLocalOobData(u8, OobData), + GenerateLocalOobData(u8, Box), // Box OobData as its size is much bigger than others LeRandCallback(u64), // key_missing_cb } @@ -1113,7 +1113,7 @@ u32 -> BtStatus, *mut RawAddress, bindings::bt_acl_state_t -> BtAclState, i32 -> let _1 = unsafe { *(_1 as *const RawAddress) }; }); -cb_variant!(BaseCb, generate_local_oob_data_cb -> BaseCallbacks::GenerateLocalOobData, u8, OobData); +cb_variant!(BaseCb, generate_local_oob_data_cb -> BaseCallbacks::GenerateLocalOobData, u8, OobData -> Box::); cb_variant!(BaseCb, le_rand_cb -> BaseCallbacks::LeRandCallback, u64); -- GitLab From 3ff256c523f17abf960e8aa0a168e1f0502421a0 Mon Sep 17 00:00:00 2001 From: Ruina Liu Date: Wed, 13 Mar 2024 11:50:04 +0000 Subject: [PATCH 0003/1446] ABS volume support is not informed to Audio sometimes Local and peer may initiate the AVRCP connection at the same time. As initiator, DUT does SDP discovery firstly. During the SDP discovery, the AVRCP profile connection initiated from peer could have finshed ahead. Then as acceptor, DUT initiate SDP discovery again. Due to the SDP discovery has already been ongoing, the new request is ignored. After SDP discovery completed, as initiator, DUT iniates the AVRCP profile connection as well but fail due to AVRCP profile connection already exist. Thus both procedure are stuck in the intermediate state. Hence neither do abs volume registration and inform the ASB support to uplayer. After SDP completed, DUT should check whether the AVRCP connection is already exist. If yes, just skip the AvrcpConnect and proceed to abs volume registration. Bug: 335331242 Test: m com.android.btservices Test with Bose Soundlink Mini, confirm that the avrcp abs volume can be correctly informed to audio no matter connection conflict happen or not. Change-Id: Ibe374f6e8c85f2c8cf5923b680fd2ab673ddc04a --- system/profile/avrcp/connection_handler.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/system/profile/avrcp/connection_handler.cc b/system/profile/avrcp/connection_handler.cc index 9881e9e6e40..4288d36872d 100644 --- a/system/profile/avrcp/connection_handler.cc +++ b/system/profile/avrcp/connection_handler.cc @@ -149,6 +149,22 @@ bool ConnectionHandler::ConnectDevice(const RawAddress& bdaddr) { } instance_->feature_map_[bdaddr] = features; + + if (com::android::bluetooth::flags::abs_volume_sdp_conflict()) { + // Peer may connect avrcp during SDP. Check the connection state when + // SDP completed to resolve the conflict. + for (const auto& pair : instance_->device_map_) { + if (bdaddr == pair.second->GetAddress()) { + log::warn("Connected by peer device with address {}", bdaddr); + if (features & BTA_AV_FEAT_ADV_CTRL) { + pair.second->RegisterVolumeChanged(); + } else if (instance_->vol_ != nullptr) { + instance_->vol_->DeviceConnected(pair.second->GetAddress()); + } + return; + } + } + } instance_->AvrcpConnect(true, bdaddr); return; }; -- GitLab From 9b69cb382ac57c7bd23cd641120897ff09965024 Mon Sep 17 00:00:00 2001 From: Ivan Lozano Date: Thu, 6 Jun 2024 15:22:37 -0400 Subject: [PATCH 0004/1446] Remove unnecessary rust_ffi entries The build system no longer allows defining rust_ffi_rlibs in static_libs for rust modules. libbt_shim_ffi isn't needed as libbt_shim is already included in rustlibs. libbluetooth_core_rs is not needed as libbluetooth_core_rs_facade is included in rustlibs. Bug: 254469782 Test: m rust Test: mma Change-Id: I513b0446216c5417906b886d1ac8d7b8896cc235 --- system/gd/rust/topshim/facade/Android.bp | 3 +-- system/rust/Android.bp | 7 +------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/system/gd/rust/topshim/facade/Android.bp b/system/gd/rust/topshim/facade/Android.bp index 5bb81175eea..2820d4803ec 100644 --- a/system/gd/rust/topshim/facade/Android.bp +++ b/system/gd/rust/topshim/facade/Android.bp @@ -43,7 +43,6 @@ rust_defaults { "libbluetooth-dumpsys", "libbluetooth-gdx", "libbluetooth-types", - "libbluetooth_core_rs", "libbluetooth_crypto_toolbox", "libbluetooth_gd", // Gabeldorsche "libbluetooth_log", @@ -78,13 +77,13 @@ rust_defaults { "libudrv-uipc", ], shared_libs: [ + "libaconfig_storage_read_api_cc", "libcrypto", "libcutils", "libgrpc++", "libgrpc_wrap", "liblog", "server_configurable_flags", - "libaconfig_storage_read_api_cc", ], proc_macros: [ "libpaste", diff --git a/system/rust/Android.bp b/system/rust/Android.bp index 71071e5828b..dfb05213233 100644 --- a/system/rust/Android.bp +++ b/system/rust/Android.bp @@ -23,8 +23,6 @@ rust_defaults { ], static_libs: [ "libbt_shim_bridge", - "libbt_shim_ffi", - "libchrome", "libevent", "libmodpb64", @@ -37,13 +35,10 @@ rust_defaults { "libanyhow", "libbitflags", "libbt_common", + "libbt_shim", "libcxx", "liblog_rust", "libscopeguard", - - // needed to work around duplicate symbols - // caused by bug in Soong - "libbt_shim", ], whole_static_libs: [ "libbluetooth_core_rs_bridge", -- GitLab From 902d659152e78b20aad3b0f9d27d8ae99c29a865 Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Thu, 6 Jun 2024 18:18:00 -0700 Subject: [PATCH 0005/1446] blueberry: Remove security gdcert tests No longer run in presubmit or postsubmit, the tests were already failing before being disabled. Bug: 333555245 Test: None Flag: EXEMPT, dead code removal Change-Id: Iccf2c497a7605be35c3ee2d3f8cd82d8d0c02ee1 --- system/blueberry/tests/gd/gd_all_tests.py | 4 +- .../blueberry/tests/gd/gd_presubmit_tests.py | 8 +- .../tests/gd/security/cert_security.py | 372 ------ .../tests/gd/security/le_security_test.py | 1127 ----------------- .../tests/gd/security/security_test.py | 552 -------- 5 files changed, 2 insertions(+), 2061 deletions(-) delete mode 100644 system/blueberry/tests/gd/security/cert_security.py delete mode 100644 system/blueberry/tests/gd/security/le_security_test.py delete mode 100644 system/blueberry/tests/gd/security/security_test.py diff --git a/system/blueberry/tests/gd/gd_all_tests.py b/system/blueberry/tests/gd/gd_all_tests.py index 5128e446dda..69fed0b1f02 100644 --- a/system/blueberry/tests/gd/gd_all_tests.py +++ b/system/blueberry/tests/gd/gd_all_tests.py @@ -24,8 +24,6 @@ from blueberry.tests.gd.hci.le_advertising_manager_test import LeAdvertisingMana from blueberry.tests.gd.hci.le_scanning_manager_test import LeScanningManagerTest from blueberry.tests.gd.hci.le_scanning_with_security_test import LeScanningWithSecurityTest from blueberry.tests.gd.iso.le_iso_test import LeIsoTest -from blueberry.tests.gd.security.le_security_test import LeSecurityTest -from blueberry.tests.gd.security.security_test import SecurityTest from blueberry.tests.gd.shim.shim_test import ShimTest from blueberry.tests.gd.shim.stack_test import StackTest @@ -34,7 +32,7 @@ from mobly import suite_runner ALL_TESTS = { CertSelfTest, SimpleHalTest, AclManagerTest, ControllerTest, DirectHciTest, LeAclManagerTest, LeAdvertisingManagerTest, LeScanningManagerTest, LeScanningWithSecurityTest, LeIsoTest, - LeSecurityTest, SecurityTest, ShimTest, StackTest + ShimTest, StackTest } DISABLED_TESTS = set() diff --git a/system/blueberry/tests/gd/gd_presubmit_tests.py b/system/blueberry/tests/gd/gd_presubmit_tests.py index 80464a1f5b0..633d637c23b 100644 --- a/system/blueberry/tests/gd/gd_presubmit_tests.py +++ b/system/blueberry/tests/gd/gd_presubmit_tests.py @@ -21,13 +21,7 @@ from mobly import suite_runner # TODO(b/194723246): Investigate failures to re-activate the test class. from blueberry.tests.gd.hci.le_scanning_manager_test import LeScanningManagerTest -# TODO(b/194723246): Investigate failures to re-activate the test class. -from blueberry.tests.gd.security.le_security_test import LeSecurityTest - -# TODO(b/194723246): Investigate failures to re-activate the test class. -from blueberry.tests.gd.security.security_test import SecurityTest - -DISABLED_TESTS = {LeScanningManagerTest, LeSecurityTest, SecurityTest} +DISABLED_TESTS = {LeScanningManagerTest} PRESUBMIT_TESTS = list(ALL_TESTS - DISABLED_TESTS) diff --git a/system/blueberry/tests/gd/security/cert_security.py b/system/blueberry/tests/gd/security/cert_security.py deleted file mode 100644 index 37528554a38..00000000000 --- a/system/blueberry/tests/gd/security/cert_security.py +++ /dev/null @@ -1,372 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2020 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging - -from blueberry.tests.gd.cert.captures import HciCaptures -from blueberry.tests.gd.cert.closable import safeClose -from blueberry.tests.gd.cert.event_stream import EventStream -from blueberry.tests.gd.cert.matchers import HciMatchers -from blueberry.tests.gd.cert.py_hci import PyHci -from blueberry.tests.gd.cert.py_security import PySecurity -from blueberry.tests.gd.cert.truth import assertThat -from google.protobuf import empty_pb2 as empty_proto -from blueberry.facade.l2cap.classic import facade_pb2 as l2cap_facade -from blueberry.facade.security.facade_pb2 import IoCapabilities -from blueberry.facade.security.facade_pb2 import AuthenticationRequirements -from blueberry.facade.security.facade_pb2 import OobDataPresent -from blueberry.utils import bluetooth -import hci_packets as hci - - -class CertSecurity(PySecurity): - """ - Contain all of the certification stack logic for sending and receiving - HCI commands following the Classic Pairing flows. - """ - _io_cap_lookup = { - IoCapabilities.DISPLAY_ONLY: hci.IoCapability.DISPLAY_ONLY, - IoCapabilities.DISPLAY_YES_NO_IO_CAP: hci.IoCapability.DISPLAY_YES_NO, - IoCapabilities.KEYBOARD_ONLY: hci.IoCapability.KEYBOARD_ONLY, - IoCapabilities.NO_INPUT_NO_OUTPUT: hci.IoCapability.NO_INPUT_NO_OUTPUT, - } - - _auth_req_lookup = { - AuthenticationRequirements.NO_BONDING: - hci.AuthenticationRequirements.NO_BONDING, - AuthenticationRequirements.NO_BONDING_MITM_PROTECTION: - hci.AuthenticationRequirements.NO_BONDING_MITM_PROTECTION, - AuthenticationRequirements.DEDICATED_BONDING: - hci.AuthenticationRequirements.DEDICATED_BONDING, - AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION: - hci.AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION, - AuthenticationRequirements.GENERAL_BONDING: - hci.AuthenticationRequirements.GENERAL_BONDING, - AuthenticationRequirements.GENERAL_BONDING_MITM_PROTECTION: - hci.AuthenticationRequirements.GENERAL_BONDING_MITM_PROTECTION, - } - - _oob_present_lookup = { - OobDataPresent.NOT_PRESENT: hci.OobDataPresent.NOT_PRESENT, - OobDataPresent.P192_PRESENT: hci.OobDataPresent.P_192_PRESENT, - OobDataPresent.P256_PRESENT: hci.OobDataPresent.P_256_PRESENT, - OobDataPresent.P192_AND_256_PRESENT: hci.OobDataPresent.P_192_AND_256_PRESENT, - } - - _hci_event_stream = None - _io_caps = hci.IoCapability.DISPLAY_ONLY - _auth_reqs = hci.AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION - _secure_connections_enabled = False - - _hci = None - - MAX_PIN_LENGTH = 16 - MIN_PIN_LENGTH = 1 - - def _enqueue_hci_command(self, command, expect_complete): - if (expect_complete): - self._hci.send_command(command) - else: - self._hci.send_command(command) - - def __init__(self, device): - """ - Don't call super b/c the gRPC stream setup will crash test - """ - logging.info("Cert: Init") - self._device = device - self._device.wait_channel_ready() - self._hci = PyHci(device) - self._hci.register_for_events(hci.EventCode.ENCRYPTION_CHANGE, - hci.EventCode.CHANGE_CONNECTION_LINK_KEY_COMPLETE, - hci.EventCode.CENTRAL_LINK_KEY_COMPLETE, hci.EventCode.RETURN_LINK_KEYS, - hci.EventCode.PIN_CODE_REQUEST, hci.EventCode.LINK_KEY_REQUEST, - hci.EventCode.LINK_KEY_NOTIFICATION, - hci.EventCode.ENCRYPTION_KEY_REFRESH_COMPLETE, - hci.EventCode.IO_CAPABILITY_REQUEST, hci.EventCode.IO_CAPABILITY_RESPONSE, - hci.EventCode.REMOTE_OOB_DATA_REQUEST, hci.EventCode.SIMPLE_PAIRING_COMPLETE, - hci.EventCode.USER_PASSKEY_NOTIFICATION, hci.EventCode.KEYPRESS_NOTIFICATION, - hci.EventCode.USER_CONFIRMATION_REQUEST, hci.EventCode.USER_PASSKEY_REQUEST) - self._hci_event_stream = self._hci.get_event_stream() - - def create_bond(self, address, type): - """ - Creates a bond from the cert perspective - """ - logging.info("Cert: Creating bond to '%s' from '%s'" % (str(address), str(self._device.address))) - # TODO(optedoblivion): Trigger connection to Send AuthenticationRequested - - def remove_bond(self, address, type): - """ - We store the link key locally in the test and pretend - So to remove_bond we need to Remove the "stored" data - """ - pass - - def set_io_capabilities(self, io_capabilities): - """ - Set the IO Capabilities used for the cert - """ - logging.info("Cert: setting IO Capabilities data to '%s'" % - self._io_capabilities_name_lookup.get(io_capabilities, "ERROR")) - self._io_caps = self._io_cap_lookup.get(io_capabilities, hci.IoCapability.DISPLAY_ONLY) - - def set_authentication_requirements(self, auth_reqs): - """ - Establish authentication requirements for the stack - """ - logging.info("Cert: setting Authentication Requirements data to '%s'" % - self._auth_reqs_name_lookup.get(auth_reqs, "ERROR")) - self._auth_reqs = self._auth_req_lookup.get(auth_reqs, hci.AuthenticationRequirements.GENERAL_BONDING) - - def get_oob_data_from_controller(self, pb_oob_data_type): - """ - Get the Out-of-band data for SSP pairing - - :param pb_oob_data_type: Type of data needed - :return: a tuple of bytes (192c,192r,256c,256r) with increasing security; bytes may be all 0s depending on pb_oob_data_type value - - """ - oob_data_type = self._oob_present_lookup[pb_oob_data_type] - - if (oob_data_type == hci.OobDataPresent.NOT_PRESENT): - logging.warn("No data present, no need to call get_oob_data") - return ([0 for i in range(0, 16)], [0 for i in range(0, 16)], [0 for i in range(0, 16)], - [0 for i in range(0, 16)]) - - logging.info("Cert: Requesting OOB data") - if oob_data_type == hci.OobDataPresent.P_192_PRESENT: - # If host and controller supports secure connections we always used ReadLocalOobExtendedDataRequest - if self._secure_connections_enabled: - logging.info("Cert: Requesting P192 Data; secure connections") - complete_capture = HciCaptures.ReadLocalOobExtendedDataCompleteCapture() - self._enqueue_hci_command(hci.ReadLocalOobExtendedData(), True) - logging.info("Cert: Waiting for OOB response from controller") - assertThat(self._hci_event_stream).emits(complete_capture) - complete = complete_capture.get() - return (list(complete.c192), list(complete.r192), [0 for i in range(0, 16)], [0 for i in range(0, 16)]) - # else we use ReadLocalDataRequest - else: - logging.info("Cert: Requesting P192 Data; no secure connections") - complete_capture = HciCaptures.ReadLocalOobDataCompleteCapture() - self._enqueue_hci_command(hci.ReadLocalOobData(), True) - logging.info("Cert: Waiting for OOB response from controller") - assertThat(self._hci_event_stream).emits(complete_capture) - complete = complete_capture.get() - return (list(complete.c), list(complete.r), [0 for i in range(0, 16)], [0 for i in range(0, 16)]) - - # Must be secure connection compatible to use these - elif oob_data_type == hci.OobDataPresent.P_256_PRESENT: - logging.info("Cert: Requesting P256 Extended Data; secure connections") - complete_capture = HciCaptures.ReadLocalOobExtendedDataCompleteCapture() - self._enqueue_hci_command(hci.ReadLocalOobExtendedData(), True) - logging.info("Cert: Waiting for OOB response from controller") - assertThat(self._hci_event_stream).emits(complete_capture) - complete = complete_capture.get() - return ([0 for i in range(0, 16)], [0 for i in range(0, 16)], list(complete.c256), list(complete.r256)) - - else: # Both - logging.info("Cert: Requesting P192 AND P256 Extended Data; secure connections") - complete_capture = HciCaptures.ReadLocalOobExtendedDataCompleteCapture() - self._enqueue_hci_command(hci.ReadLocalOobExtendedData(), True) - logging.info("Cert: Waiting for OOB response from controller") - assertThat(self._hci_event_stream).emits(complete_capture) - complete = complete_capture.get() - return (list(complete.c192), list(complete.r192), list(complete.c256), list(complete.r256)) - - def input_passkey(self, address, passkey): - """ - Pretend to answer the pairing dialog as a user - """ - logging.info("Cert: Waiting for PASSKEY request") - assertThat(self._hci_event_stream).emits(HciMatchers.EventWithCode(hci.EventCode.USER_PASSKEY_REQUEST)) - logging.info("Cert: Send user input passkey %d for %s" % (passkey, address)) - peer = bluetooth.Address(address) - self._enqueue_hci_command( - hci.SendKeypressNotification(bd_addr=peer, notification_type=hci.KeypressNotificationType.ENTRY_STARTED), - True) - self._enqueue_hci_command( - hci.SendKeypressNotification(bd_addr=peer, notification_type=hci.KeypressNotificationType.DIGIT_ENTERED), - True) - self._enqueue_hci_command( - hci.SendKeypressNotification(bd_addr=peer, notification_type=hci.KeypressNotificationType.DIGIT_ENTERED), - True) - self._enqueue_hci_command( - hci.SendKeypressNotification(bd_addr=peer, notification_type=hci.KeypressNotificationType.CLEARED), True) - self._enqueue_hci_command( - hci.SendKeypressNotification(bd_addr=peer, notification_type=hci.KeypressNotificationType.DIGIT_ENTERED), - True) - self._enqueue_hci_command( - hci.SendKeypressNotification(bd_addr=peer, notification_type=hci.KeypressNotificationType.DIGIT_ENTERED), - True) - self._enqueue_hci_command( - hci.SendKeypressNotification(bd_addr=peer, notification_type=hci.KeypressNotificationType.DIGIT_ERASED), - True) - self._enqueue_hci_command( - hci.SendKeypressNotification(bd_addr=peer, notification_type=hci.KeypressNotificationType.DIGIT_ENTERED), - True) - self._enqueue_hci_command( - hci.SendKeypressNotification(bd_addr=peer, notification_type=hci.KeypressNotificationType.DIGIT_ENTERED), - True) - self._enqueue_hci_command( - hci.SendKeypressNotification(bd_addr=peer, notification_type=hci.KeypressNotificationType.DIGIT_ENTERED), - True) - self._enqueue_hci_command( - hci.SendKeypressNotification(bd_addr=peer, notification_type=hci.KeypressNotificationType.DIGIT_ENTERED), - True) - self._enqueue_hci_command( - hci.SendKeypressNotification(bd_addr=peer, notification_type=hci.KeypressNotificationType.DIGIT_ENTERED), - True) - self._enqueue_hci_command( - hci.SendKeypressNotification(bd_addr=peer, notification_type=hci.KeypressNotificationType.ENTRY_COMPLETED), - True) - self._enqueue_hci_command(hci.UserPasskeyRequestReply(bd_addr=peer, numeric_value=passkey), True) - - def input_pin(self, address, pin): - """ - Pretend to answer the pairing dialog as a user - """ - - if len(pin) > self.MAX_PIN_LENGTH or len(pin) < self.MIN_PIN_LENGTH: - raise Exception("Pin code must be within range") - - logging.info("Cert: Waiting for PIN request") - assertThat(self._hci_event_stream).emits(HciMatchers.PinCodeRequest()) - logging.info("Cert: Send user input PIN %s for %s" % (pin.decode(), address)) - peer = address.decode('utf-8') - pin_list = list(pin) - # Pad - for i in range(self.MAX_PIN_LENGTH - len(pin_list)): - pin_list.append(0) - self._enqueue_hci_command( - hci.PinCodeRequestReply(bd_addr=bluetooth.Address(peer), pin_code_length=len(pin), pin_code=pin_list), True) - - def __send_ui_callback(self, address, callback_type, b, uid, pin): - """ - Pretend to answer the pairing dailog as a user - """ - logging.info("Cert: Send user input callback uid:%d; response: %s" % (uid, b)) - # TODO(optedoblivion): Make callback and set it to the module - - def enable_secure_simple_pairing(self): - """ - This is called when you want to enable SSP for testing - """ - logging.info("Cert: Sending WRITE_SIMPLE_PAIRING_MODE [True]") - self._enqueue_hci_command(hci.WriteSimplePairingMode(simple_pairing_mode=hci.Enable.ENABLED), True) - logging.info("Cert: Waiting for controller response") - assertThat(self._hci_event_stream).emits(HciMatchers.CommandComplete(hci.OpCode.WRITE_SIMPLE_PAIRING_MODE)) - - def enable_secure_connections(self): - """ - This is called when you want to enable secure connections support - """ - logging.info("Cert: Sending WRITE_SECURE_CONNECTIONS_HOST_SUPPORT [True]") - self._enqueue_hci_command( - hci.WriteSecureConnectionsHostSupport(secure_connections_host_support=hci.Enable.ENABLED), True) - logging.info("Cert: Waiting for controller response") - assertThat(self._hci_event_stream).emits( - HciMatchers.CommandComplete(hci.OpCode.WRITE_SECURE_CONNECTIONS_HOST_SUPPORT)) - # TODO(optedoblivion): Figure this out and remove (see classic_pairing_handler.cc) - #self._secure_connections_enabled = True - - def send_io_caps(self, address): - logging.info("Cert: Waiting for IO_CAPABILITY_REQUEST") - assertThat(self._hci_event_stream).emits(HciMatchers.IoCapabilityRequest()) - logging.info("Cert: Sending IO_CAPABILITY_REQUEST_REPLY") - oob_data_present = hci.OobDataPresent.NOT_PRESENT - self._enqueue_hci_command( - hci.IoCapabilityRequestReply(bd_addr=bluetooth.Address(address), - io_capability=self._io_caps, - oob_present=oob_data_present, - authentication_requirements=self._auth_reqs), True) - - def accept_pairing(self, dut_address, reply_boolean, expect_to_fail, on_responder_reply): - """ - Here we handle the pairing events at the HCI level - """ - logging.info("Cert: Waiting for IO_CAPABILITY_RESPONSE") - assertThat(self._hci_event_stream).emits(HciMatchers.IoCapabilityResponse()) - self.send_io_caps(dut_address) - logging.info("Cert: Waiting for USER_CONFIRMATION_REQUEST") - assertThat(self._hci_event_stream).emits(HciMatchers.UserConfirmationRequest()) - logging.info("Cert: Sending Simulated User Response '%s'" % reply_boolean) - if reply_boolean: - logging.info("Cert: Sending USER_CONFIRMATION_REQUEST_REPLY") - self._enqueue_hci_command(hci.UserConfirmationRequestReply(bd_addr=bluetooth.Address(dut_address)), True) - on_responder_reply() - logging.info("Cert: Waiting for SIMPLE_PAIRING_COMPLETE") - assertThat(self._hci_event_stream).emits(HciMatchers.SimplePairingComplete()) - if not expect_to_fail: - logging.info("Cert: Waiting for LINK_KEY_NOTIFICATION") - assertThat(self._hci_event_stream).emits(HciMatchers.LinkKeyNotification()) - else: - logging.info("Cert: Sending USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY") - self._enqueue_hci_command(hci.UserConfirmationRequestNegativeReply(bd_addr=bluetooth.Address(dut_address)), - True) - on_responder_reply() - logging.info("Cert: Waiting for SIMPLE_PAIRING_COMPLETE") - assertThat(self._hci_event_stream).emits(HciMatchers.SimplePairingComplete()) - - def accept_oob_pairing(self, dut_address): - logging.info("Cert: Waiting for IO_CAPABILITY_RESPONSE") - assertThat(self._hci_event_stream).emits(HciMatchers.IoCapabilityResponse()) - self.send_io_caps(dut_address) - logging.info("Cert: Waiting for SIMPLE_PAIRING_COMPLETE") - ssp_complete_capture = HciCaptures.SimplePairingCompleteCapture() - assertThat(self._hci_event_stream).emits(ssp_complete_capture) - ssp_complete = ssp_complete_capture.get() - logging.info(ssp_complete.status) - assertThat(ssp_complete.status).isEqualTo(hci.ErrorCode.SUCCESS) - - def on_user_input(self, dut_address, reply_boolean, expected_ui_event): - """ - Cert doesn't need the test to respond to the ui event - Cert responds in accept pairing - """ - pass - - def wait_for_bond_event(self, expected_bond_event): - """ - A bond event will be triggered once the bond process - is complete. For the DUT we need to wait for it, - for Cert it isn't needed. - """ - pass - - def enforce_security_policy(self, address, type, policy): - """ - Pass for now - """ - pass - - def wait_for_enforce_security_event(self, expected_enforce_security_event): - """ - Cert side needs to pass - """ - pass - - def wait_for_disconnect_event(self): - """ - Cert side needs to pass - """ - pass - # FIXME: Gabeldorsche facade don't allow us to register for an DISCONNECT_COMPLETE event - # logging.info("Cert: Waiting for DISCONNECT_COMPLETE") - # assertThat(self._hci_event_stream).emits(HciMatchers.DisconnectionComplete()) - - def close(self): - safeClose(self._hci) diff --git a/system/blueberry/tests/gd/security/le_security_test.py b/system/blueberry/tests/gd/security/le_security_test.py deleted file mode 100644 index 6368c30f434..00000000000 --- a/system/blueberry/tests/gd/security/le_security_test.py +++ /dev/null @@ -1,1127 +0,0 @@ -# -# Copyright 2019 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import hci_packets as hci -import smp_packets as smp -from blueberry.tests.gd.cert.matchers import SecurityMatchers -from blueberry.tests.gd.cert.metadata import metadata -from blueberry.tests.gd.cert.py_hci import PyHci -from blueberry.tests.gd.cert.py_le_security import PyLeSecurity -from blueberry.tests.gd.cert.truth import assertThat -from blueberry.tests.gd.cert import gd_base_test -from datetime import timedelta -from blueberry.facade import common_pb2 as common -from blueberry.facade.hci import le_advertising_manager_facade_pb2 as le_advertising_facade -from blueberry.facade.hci import le_initiator_address_facade_pb2 as le_initiator_address_facade -from google.protobuf import empty_pb2 as empty_proto -from blueberry.facade.security.facade_pb2 import BondMsgType -from blueberry.facade.security.facade_pb2 import OobDataMessage -from blueberry.facade.security.facade_pb2 import UiCallbackMsg -from blueberry.facade.security.facade_pb2 import UiCallbackType -from blueberry.facade.security.facade_pb2 import UiMsgType -from blueberry.facade.security.facade_pb2 import LeIoCapabilityMessage -from blueberry.facade.security.facade_pb2 import LeOobDataPresentMessage -from blueberry.facade.security.facade_pb2 import LeMaximumEncryptionKeySizeMessage -from mobly import asserts -from mobly import test_runner - -LeIoCapabilities = LeIoCapabilityMessage.LeIoCapabilities -LeOobDataFlag = LeOobDataPresentMessage.LeOobDataFlag - -DISPLAY_ONLY = LeIoCapabilityMessage(capabilities=LeIoCapabilities.DISPLAY_ONLY) -KEYBOARD_ONLY = LeIoCapabilityMessage(capabilities=LeIoCapabilities.KEYBOARD_ONLY) -NO_INPUT_NO_OUTPUT = LeIoCapabilityMessage(capabilities=LeIoCapabilities.NO_INPUT_NO_OUTPUT) -KEYBOARD_DISPLAY = LeIoCapabilityMessage(capabilities=LeIoCapabilities.KEYBOARD_DISPLAY) - -OOB_NOT_PRESENT = LeOobDataPresentMessage(data_present=LeOobDataFlag.NOT_PRESENT) -OOB_PRESENT = LeOobDataPresentMessage(data_present=LeOobDataFlag.PRESENT) - - -class LeSecurityTest(gd_base_test.GdBaseTestClass): - - def setup_class(self): - gd_base_test.GdBaseTestClass.setup_class(self, dut_module='SECURITY', cert_module='SECURITY') - - def setup_test(self): - asserts.skip("Unhandled race condition - Flaky test") - gd_base_test.GdBaseTestClass.setup_test(self) - - self.dut_security = PyLeSecurity(self.dut) - self.cert_security = PyLeSecurity(self.cert) - self.dut_hci = PyHci(self.dut) - - raw_addr = self.dut.hci_controller.GetMacAddress(empty_proto.Empty()).address - - self.dut_address = common.BluetoothAddressWithType(address=common.BluetoothAddress(address=raw_addr), - type=common.PUBLIC_DEVICE_ADDRESS) - privacy_policy = le_initiator_address_facade.PrivacyPolicy( - address_policy=le_initiator_address_facade.AddressPolicy.USE_PUBLIC_ADDRESS, - address_with_type=self.dut_address) - self.dut.security.SetLeInitiatorAddressPolicy(privacy_policy) - self.cert_address = common.BluetoothAddressWithType(address=common.BluetoothAddress( - address=self.cert.hci_controller.GetMacAddress(empty_proto.Empty()).address), - type=common.PUBLIC_DEVICE_ADDRESS) - cert_privacy_policy = le_initiator_address_facade.PrivacyPolicy( - address_policy=le_initiator_address_facade.AddressPolicy.USE_PUBLIC_ADDRESS, - address_with_type=self.cert_address) - self.cert.security.SetLeInitiatorAddressPolicy(cert_privacy_policy) - - def teardown_test(self): - return # test skipped - self.dut_hci.close() - self.dut_security.close() - self.cert_security.close() - gd_base_test.GdBaseTestClass.teardown_test(self) - - def _prepare_cert_for_connection(self): - # DUT Advertises - gap_name = hci.GapData(data_type=hci.GapDataType.COMPLETE_LOCAL_NAME, data=list(bytes(b'Im_The_CERT'))) - gap_data = le_advertising_facade.GapDataMsg(data=gap_name.serialize()) - config = le_advertising_facade.AdvertisingConfig( - advertisement=[gap_data], - interval_min=512, - interval_max=768, - advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND, - own_address_type=common.USE_PUBLIC_DEVICE_ADDRESS, - channel_map=7, - filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES) - request = le_advertising_facade.CreateAdvertiserRequest(config=config) - create_response = self.cert.hci_le_advertising_manager.CreateAdvertiser(request) - - def _prepare_dut_for_connection(self): - # DUT Advertises - gap_name = hci.GapData(data_type=hci.GapDataType.COMPLETE_LOCAL_NAME, data=list(bytes(b'Im_The_DUT'))) - gap_data = le_advertising_facade.GapDataMsg(data=gap_name.serialize()) - config = le_advertising_facade.AdvertisingConfig( - advertisement=[gap_data], - interval_min=512, - interval_max=768, - advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND, - own_address_type=common.USE_PUBLIC_DEVICE_ADDRESS, - channel_map=7, - filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES) - request = le_advertising_facade.CreateAdvertiserRequest(config=config) - create_response = self.dut.hci_le_advertising_manager.CreateAdvertiser(request) - - @metadata(pts_test_id="SM/MAS/PROT/BV-01-C", pts_test_name="SMP Time Out – IUT Initiator") - def test_le_smp_timeout_iut_initiator(self): - """ - Verify that the IUT handles the lack of pairing response after 30 seconds when acting as initiator. - """ - self._prepare_cert_for_connection() - self.dut.security.CreateBondLe(self.cert_address) - assertThat(self.dut_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BOND_FAILED, self.cert_address), - timeout=timedelta(seconds=35)) - - @metadata(pts_test_id="SM/SLA/PROT/BV-02-C", pts_test_name="SMP Time Out – IUT Responder") - def test_le_smp_timeout_iut_responder(self): - """ - Verify that the IUT handles the lack of pairing response after 30 seconds when acting as initiator. - """ - self.cert.security.SetLeIoCapability(KEYBOARD_ONLY) - self.dut.security.SetLeIoCapability(DISPLAY_ONLY) - - self._prepare_dut_for_connection() - - # 1. Lower Tester transmits Pairing Request. - self.cert.security.CreateBondLe(self.dut_address) - - assertThat(self.dut_security.get_ui_stream()).emits(SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, - self.cert_address), - timeout=timedelta(seconds=35)) - - # 2. IUT responds with Pairing Response. - self.dut.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.cert_address)) - - # 3. In phase 2, Lower Tester does not issue the expected Pairing Confirm. - - # Here the cert receives DISPLAY_PASSKEY_ENTRY. By not replying to it we make sure Pairing Confirm is never sent - assertThat(self.cert_security.get_ui_stream()).emits(SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PASSKEY_ENTRY, - self.dut_address), - timeout=timedelta(seconds=5)) - - # 4. IUT times out 30 seconds after issued Pairing Response and reports the failure to the Upper Tester. - assertThat(self.dut_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BOND_FAILED, self.cert_address), - timeout=timedelta(seconds=35)) - - # 5. After additionally (at least) 10 seconds the Lower Tester issues the expected Pairing Confirm. - # 6. The IUT closes the connection before receiving the delayed response or does not respond to it when it is received. - #TODO: - #assertThat(self.dut_hci.get_event_stream()).emits(HciMatchers.Disconnect()) - - @metadata(pts_test_id="SM/MAS/JW/BV-01-C", pts_test_name="Just Works IUT Initiator – Success") - def test_just_works_iut_initiator(self): - """ - Verify that the IUT performs the Just Works pairing procedure correctly as central, initiator when both sides do not require MITM protection. - """ - self._prepare_cert_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements() - - self.cert.security.SetLeIoCapability(DISPLAY_ONLY) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements() - - # 1. IUT transmits Pairing Request command with: - # a. IO capability set to any IO capability - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. AuthReq Bonding Flags set to ‘00’ and the MITM flag set to ‘0’ and all the reserved bits are set to ‘0’ - self.dut.security.CreateBondLe(self.cert_address) - - assertThat(self.cert_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.dut_address)) - - # 2. Lower Tester responds with a Pairing Response command, with: - # a. IO capability set to “KeyboardDisplay” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. AuthReq Bonding Flags set to ‘00’, and the MITM flag set to ‘0’ and all the reserved bits are set to ‘0’ - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.dut_address)) - - # 3. IUT and Lower Tester perform phase 2 of the just works pairing procedure and establish an encrypted link with the key generated in phase 2. - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) - - @metadata(pts_test_id="SM/SLA/JW/BV-02-C", pts_test_name="Just Works IUT Responder – Success") - def test_just_works_iut_responder(self): - """ - Verify that the IUT is able to perform the Just Works pairing procedure correctly when acting as peripheral, responder. - """ - self._prepare_dut_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements() - - self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements() - - # 1. Lower Tester transmits Pairing Request command with: - # a. IO capability set to “NoInputNoOutput” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. MITM flag set to ‘0’ and all reserved bits are set to ‘0’ - self.cert.security.CreateBondLe(self.dut_address) - - assertThat(self.dut_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) - - # 2. IUT responds with a Pairing Response command, with: - # a. IO capability set to any IO capability - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - self.dut.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.cert_address)) - - # IUT and Lower Tester perform phase 2 of the just works pairing and establish an encrypted link with the generated STK. - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) - - @metadata(pts_test_id="SM/SLA/JW/BI-03-C", - pts_test_name="Just Works IUT Responder – Handle AuthReq flag RFU correctly") - def test_just_works_iut_responder_auth_req_rfu(self): - """ - Verify that the IUT is able to perform the Just Works pairing procedure when receiving additional bits set in the AuthReq flag. Reserved For Future Use bits are correctly handled when acting as peripheral, responder. - """ - self._prepare_dut_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_DISPLAY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements() - - self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements(mitm=1, secure_connections=1, reserved_bits=2) - - # 1. Lower Tester transmits Pairing Request command with: - # a. IO Capability set to ”NoInputNoOutput” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. MITM set to ‘0’ and all reserved bits are set to ‘1’ - self.cert.security.CreateBondLe(self.dut_address) - - assertThat(self.dut_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) - - # 2. IUT responds with a Pairing Response command, with: - # a. IO capability set to any IO capability - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. All reserved bits are set to ‘0’ - self.dut.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.cert_address)) - - # 3. IUT and Lower Tester perform phase 2 of the just works pairing and establish an encrypted link with the generated STK. - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) - - @metadata(pts_test_id="SM/MAS/JW/BI-04-C", - pts_test_name="Just Works IUT Initiator – Handle AuthReq flag RFU correctly") - def test_just_works_iut_initiator_auth_req_rfu(self): - """ - Verify that the IUT is able to perform the Just Works pairing procedure when receiving additional bits set in the AuthReq flag. Reserved For Future Use bits are correctly handled when acting as central, initiator. - """ - self._prepare_cert_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_DISPLAY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements() - - self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements(mitm=1, secure_connections=1, reserved_bits=3) - - # 1. IUT transmits a Pairing Request command with: - # a. IO Capability set to any IO Capability - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. All reserved bits are set to ‘0’. For the purposes of this test the Secure Connections bit and the Keypress bits in the AuthReq bonding flag set by the IUT are ignored by the Lower Tester. - self.dut.security.CreateBondLe(self.cert_address) - - assertThat(self.cert_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.dut_address)) - - # 2. Lower Tester responds with a Pairing Response command, with: - # a. IO Capability set to “NoInputNoOutput” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. AuthReq bonding flag set to the value indicated in the IXIT [7] for ‘Bonding Flags’ and the MITM flag set to ‘0’ and all reserved bits are set to ‘1’. The SC and Keypress bits in the AuthReq bonding flag are set to 0 by the Lower Tester for this test. - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.dut_address)) - - # 3. IUT and Lower Tester perform phase 2 of the just works pairing and establish an encrypted link with the generated STK. - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) - - @metadata(pts_test_id="SM/MAS/SCJW/BV-01-C", - pts_test_name="Just Works, IUT Initiator, Secure Connections – Success") - def test_just_works_iut_initiator_secure_connections(self): - """ - Verify that the IUT supporting LE Secure Connections performs the Just Works or Numeric Comparison pairing procedure correctly as initiator. - """ - self._prepare_cert_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements(secure_connections=1) - - self.cert.security.SetLeIoCapability(DISPLAY_ONLY) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements(secure_connections=1) - - # 1. IUT transmits Pairing Request command with: - # a. IO capability set to any IO capability - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. AuthReq Bonding Flags set to ‘00’, the MITM flag set to either ‘0’ for Just Works or '1' for Numeric Comparison, Secure Connections flag set to '1' and all the reserved bits are set to ‘0’ - self.dut.security.CreateBondLe(self.cert_address) - - assertThat(self.cert_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.dut_address)) - - # 2. Lower Tester responds with a Pairing Response command, with: - # a. IO capability set to “KeyboardDisplay” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. AuthReq Bonding Flags set to ‘00’, the MITM flag set to ‘0’, Secure Connections flag set to '1' and all the reserved bits are set to ‘0’ - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.dut_address)) - - # 3. IUT and Lower Tester perform phase 2 of the Just Works or Numeric Comparison pairing procedure according to the MITM flag and IO capabilities, and establish an encrypted link with the LTK generated in phase 2. - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) - - @metadata(pts_test_id="SM/SLA/SCJW/BV-02-C", - pts_test_name="Just Works, IUT Responder, Secure Connections – Success") - def test_just_works_iut_responder_secure_connections(self): - """ - Verify that the IUT supporting LE Secure Connections is able to perform the Just Works or Numeric Comparison pairing procedure correctly when acting as responder. - """ - self._prepare_dut_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements(secure_connections=1) - - self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements(secure_connections=1) - - # 1. Lower Tester transmits Pairing Request command with: - # a. IO capability set to “NoInputNoOutput” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. AuthReq Bonding Flags set to ‘00’, MITM flag set to ‘0’, Secure Connections flag set to '1' and all reserved bits are set to ‘0’ - self.cert.security.CreateBondLe(self.dut_address) - - assertThat(self.dut_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) - - # 2. IUT responds with a Pairing Response command, with: - # a. IO capability set to any IO capability - # b. AuthReq Bonding Flags set to ‘00’, MITM flag set to either ‘0’ for Just Works or '1' for Numeric Comparison, Secure Connections flag set to '1' and all reserved bits are set to ‘0’ - self.dut.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.cert_address)) - - # 3. UT and Lower Tester perform phase 2 of the Just Works or Numeric Comparison pairing procedure according to the MITM flag and IO capabilities, and establish an encrypted link with the LTK generated in phase 2. - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) - - @metadata(pts_test_id="SM/SLA/SCJW/BV-03-C", - pts_test_name="Just Works, IUT Responder, Secure Connections – Handle AuthReq Flag RFU Correctly") - def test_just_works_iut_responder_secure_connections_auth_req_rfu(self): - """ - Verify that the IUT is able to perform the Just Works pairing procedure when receiving additional bits set in the AuthReq flag. Reserved For Future Use bits are correctly handled when acting as peripheral, responder. - """ - self._prepare_dut_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_DISPLAY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements(secure_connections=1) - - self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements(mitm=1, secure_connections=1, reserved_bits=3) - - # 1. Lower Tester transmits Pairing Request command with: - # a. IO Capability set to ”NoInputNoOutput” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. MITM set to ‘0’ and all reserved bits are set to a random value. - self.cert.security.CreateBondLe(self.dut_address) - - assertThat(self.dut_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) - - # 2. IUT responds with a Pairing Response command, with: - # a. IO capability set to any IO capability - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. All reserved bits are set to ‘0’ - self.dut.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.cert_address)) - - # 3. IUT and Lower Tester perform phase 2 of the Just Works pairing and establish an encrypted link with the generated LTK. - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) - - @metadata(pts_test_id="SM/MAS/SCJW/BV-04-C", - pts_test_name="Just Works, IUT Initiator, Secure Connections – Handle AuthReq Flag RFU Correctly") - def test_just_works_iut_initiator_secure_connections_auth_req_rfu(self): - """ - Verify that the IUT is able to perform the Just Works pairing procedure when receiving additional bits set in the AuthReq flag. Reserved For Future Use bits are correctly handled when acting as central, initiator. - """ - self._prepare_cert_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_DISPLAY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements(secure_connections=1) - - self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements(mitm=1, secure_connections=1, reserved_bits=3) - - # 1. IUT transmits a Pairing Request command with: - # a. IO Capability set to any IO Capability - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. All reserved bits are set to ‘0’. - self.dut.security.CreateBondLe(self.cert_address) - - assertThat(self.cert_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.dut_address)) - - # 2. Lower Tester responds with a Pairing Response command, with: - # a. IO Capability set to “NoInputNoOutput” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. AuthReq bonding flag set to the value indicated in the IXIT [7] for ‘Bonding Flags’ and the MITM flag set to ‘0’ and all reserved bits are set to a random value. - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.dut_address)) - - # 3. IUT and Lower Tester perform phase 2 of the Just Works pairing and establish an encrypted link with the generated LTK. - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) - - @metadata(pts_test_id="SM/MAS/EKS/BV-01-C", - pts_test_name="IUT initiator, Lower Tester Maximum Encryption Key Size = Min_Encryption_Key_Length") - def test_min_encryption_key_size_equal_to_max_iut_initiator(self): - """ - Verify that the IUT uses correct key size during encryption as initiator. - """ - self._prepare_cert_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_DISPLAY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements(secure_connections=1) - self.dut.security.SetLeMaximumEncryptionKeySize( - LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x10)) - - self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements(mitm=1, secure_connections=1) - self.cert.security.SetLeMaximumEncryptionKeySize( - LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x07)) - - # 1. IUT transmits a Pairing Request - self.dut.security.CreateBondLe(self.cert_address) - - assertThat(self.cert_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.dut_address)) - - # 2. Lower Tester responds with Pairing Response command with Maximum Encryption Key Size field set to Min_Encryption_Key_Length’. - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.dut_address)) - - # 3. IUT and Lower Tester perform phase 2 of the LE pairing and establish an encrypted link with the key generated in phase 2. - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) - - @metadata(pts_test_id="SM/SLA/EKS/BV-02-C", - pts_test_name="IUT Responder, Lower Tester Maximum Encryption Key Size = Min_Encryption_Key_Length") - def test_min_encryption_key_size_equal_to_max_iut_responder(self): - """ - Verify that the IUT uses correct key size during encryption as responder. - """ - self._prepare_dut_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements() - self.dut.security.SetLeMaximumEncryptionKeySize( - LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x07)) - - self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements() - self.cert.security.SetLeMaximumEncryptionKeySize( - LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x10)) - - # 1. Lower Tester initiates Pairing Request command with Maximum Encryption Key Size field set to Min_Encryption_Key_Length’. - self.cert.security.CreateBondLe(self.dut_address) - - assertThat(self.dut_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) - - # 2. IUT responds with Pairing Response command. - self.dut.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.cert_address)) - - #3. IUT and Lower Tester perform phase 2 of the LE pairing and establish an encrypted link with the key generated in phase 2. - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED, self.cert_address)) - - @metadata(pts_test_id="SM/MAS/EKS/BI-01-C", - pts_test_name="IUT initiator, Lower Tester Maximum Encryption Key Size < Min_Encryption_Key_Length") - def test_min_encryption_key_size_less_than_min_iut_initiator(self): - """ - Verify that the IUT checks that the resultant encryption key size is not smaller than the minimum key size. - """ - self._prepare_cert_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_DISPLAY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements(secure_connections=1) - self.dut.security.SetLeMaximumEncryptionKeySize( - LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x10)) - - self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements(mitm=1, secure_connections=1) - self.cert.security.SetLeMaximumEncryptionKeySize( - LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x06)) - - # 1. IUT transmits a Pairing Request - self.dut.security.CreateBondLe(self.cert_address) - - assertThat(self.cert_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.dut_address)) - - # 2. Lower Tester responds with Pairing Response command with Maximum Encryption Key Size field set to Min_Encryption_Key_Length-1’. - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.dut_address)) - - # 3. IUT transmits the Pairing Failed command. - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_BOND_FAILED, self.cert_address, - int(smp.PairingFailedReason.ENCRYPTION_KEY_SIZE))) - - @metadata(pts_test_id="SM/SLA/EKS/BI-02-C", - pts_test_name="IUT Responder, Lower Tester Maximum Encryption Key Size < Min_Encryption_Key_Length") - def test_min_encryption_key_size_less_than_min_iut_responder(self): - """ - Verify that the IUT uses correct key size during encryption as responder. - """ - self._prepare_dut_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements() - self.dut.security.SetLeMaximumEncryptionKeySize( - LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x06)) - - self.cert.security.SetLeIoCapability(NO_INPUT_NO_OUTPUT) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements() - self.cert.security.SetLeMaximumEncryptionKeySize( - LeMaximumEncryptionKeySizeMessage(maximum_encryption_key_size=0x10)) - - # 1. Lower Tester initiates Pairing Request command with Maximum Encryption Key Size field set to Min_Encryption_Key_Length-1. - self.cert.security.CreateBondLe(self.dut_address) - - assertThat(self.dut_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) - - self.dut.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.cert_address)) - - #3. IUT transmits the Pairing Failed command. - assertThat(self.cert_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_BOND_FAILED, self.dut_address, - int(smp.PairingFailedReason.ENCRYPTION_KEY_SIZE))) - - @metadata(pts_test_id="SM/MAS/SCPK/BV-01-C", - pts_test_name="Passkey Entry, IUT Initiator, Secure Connections – Success") - def test_passkey_entry_iut_initiator_secure_connections(self): - """ - Verify that the IUT supporting LE Secure Connections performs the Passkey Entry pairing procedure correctly as central, initiator. - """ - self._prepare_cert_for_connection() - - self.dut.security.SetLeIoCapability(DISPLAY_ONLY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements(secure_connections=1) - - self.cert.security.SetLeIoCapability(KEYBOARD_ONLY) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements(mitm=1, secure_connections=1) - - # 1. IUT transmits Pairing Request command with: - # a. IO capability set to “DisplayOnly” or “KeyboardOnly” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. AuthReq bonding flag set to ‘00’, the MITM flag set to ‘0’ and Secure Connections flag set to '1'. Keypress bit is set to '1' if supported - self.dut.security.CreateBondLe(self.cert_address) - - assertThat(self.cert_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.dut_address)) - - # 2. Lower Tester responds with a Pairing Response command, with: - # a. IO capability set to “KeyboardOnly” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. AuthReq bonding flag set to ‘00’, the MITM flag set to ‘1’, Secure Connections flag set to '1' and all reserved bits are set to ‘0’. Keypress bit is set to '1' if supported by the IUT. - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.dut_address)) - - assertThat(self.cert_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PASSKEY_ENTRY, self.dut_address)) - - # 3. During the phase 2 pairing, the IUT displays the 6-digit passkey while the Lower Tester prompts user to enter the 6-digit passkey. If the IUT’s IO capabilities are “KeyboardOnly” the passkey is not displayed and both IUT and Lower Tester enter the same 6-digit passkey. If Keypress bit is set, pairing keypress notifications are sent by the Lower Tester. - passkey = self.dut_security.wait_for_ui_event_passkey() - - if passkey == 0: - print("Passkey did not arrive into test") - - # 4. IUT and Lower Tester use the same 6-digit passkey. - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PASSKEY, - numeric_value=passkey, - unique_id=1, - address=self.dut_address)) - - # 5. IUT and Lower Tester perform phase 2 of the Passkey Entry pairing procedure and establish an encrypted link with the LTK generated in phase 2. - assertThat(self.dut_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BONDED, self.cert_address), - timeout=timedelta(seconds=10)) - - @metadata(pts_test_id="SM/SLA/SCPK/BV-02-C", - pts_test_name="Passkey Entry, IUT Responder, Secure Connections – Success") - def test_passkey_entry_iut_responder_secure_connections(self): - """ - Verify that the IUT supporting LE Secure Connections is able to perform the Passkey Entry pairing procedure correctly when acting as peripheral, responder. - """ - self._prepare_dut_for_connection() - - self.dut.security.SetLeIoCapability(DISPLAY_ONLY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements(secure_connections=1) - - self.cert.security.SetLeIoCapability(KEYBOARD_DISPLAY) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements(mitm=1, secure_connections=1) - - # 1. Lower Tester transmits Pairing Request command with: - # a. IO capability set to “KeyboardDisplay” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. AuthReq bonding flag set to the value indicated in the IXIT [7] for ‘Bonding Flags’, and the MITM flag set to ‘1’ Secure Connections flag set to '1' and all reserved bits are set to ‘0’ - self.cert.security.CreateBondLe(self.dut_address) - - assertThat(self.dut_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) - - # 2. IUT responds with a Pairing Response command, with: - # a. IO capability set to “KeyboardOnly” or “KeyboardDisplay” or “DisplayYesNo” or “DisplayOnly” - # b. Secure Connections flag set to '1'. Keypress bit is set to '1' if supported by IUT - self.dut.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.cert_address)) - - # 3. During the phase 2 passkey pairing process, Lower Tester displays the 6-digit passkey while the IUT prompts user to enter the 6-digit passkey. If the IO capabilities of the IUT are “DisplayYesNo” or “DisplayOnly” the IUT displays the 6-digit passkey while the Lower Tester enters the 6-digit passkey. If Keypress bit is set, pairing keypress notifications are send by the IUT - passkey = self.dut_security.wait_for_ui_event_passkey() - - if passkey == 0: - print("Passkey did not arrive into test") - - assertThat(self.cert_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PASSKEY_ENTRY, self.dut_address)) - - # 4. IUT and Lower Tester use the same pre-defined 6-digit passkey. - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PASSKEY, - numeric_value=passkey, - unique_id=1, - address=self.dut_address)) - - # 5. IUT and Lower Tester perform phase 2 of the LE pairing and establish an encrypted link with the LTK generated in phase 2. - assertThat(self.dut_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BONDED, self.cert_address), - timeout=timedelta(seconds=10)) - - @metadata(pts_test_id="SM/SLA/SCPK/BV-03-C", - pts_test_name="Passkey Entry, IUT Responder, Secure Connections – Handle AuthReq Flag RFU Correctly") - def test_passkey_entry_iut_responder_secure_connections_auth_req_rfu(self): - """ - Verify that the IUT supporting LE Secure Connections is able to perform the Passkey Entry pairing procedure when receiving additional bits set in the AuthReq flag. Reserved For Future Use bits are correctly handled when acting as peripheral, responder. - """ - self._prepare_dut_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements(secure_connections=1) - - self.cert.security.SetLeIoCapability(DISPLAY_ONLY) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements(mitm=1, secure_connections=1, reserved_bits=3) - - # 1. Lower Tester transmits Pairing Request command with: - # a. IO Capability set to ”KeyboardOnly” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. MITM set to ‘1’ and all reserved bits are set to a random value - self.cert.security.CreateBondLe(self.dut_address) - - assertThat(self.dut_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) - - # 2. IUT responds with a Pairing Response command, with: - # a. IO Capability set to “KeyboardOnly” or “DisplayOnly” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. All reserved bits are set to ‘0’ - self.dut.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.cert_address)) - - passkey = self.cert_security.wait_for_ui_event_passkey() - - if passkey == 0: - print("Passkey did not arrive into test") - - assertThat(self.dut_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PASSKEY_ENTRY, self.cert_address)) - - self.dut.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PASSKEY, - numeric_value=passkey, - unique_id=1, - address=self.cert_address)) - - # 3. IUT and Lower Tester perform phase 2 of the Passkey Entry pairing and establish an encrypted link with the generated LTK. - assertThat(self.dut_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BONDED, self.cert_address), - timeout=timedelta(seconds=10)) - - @metadata(pts_test_id="SM/MAS/SCPK/BV-04-C", - pts_test_name="Passkey Entry, IUT Initiator, Secure Connections – Handle AuthReq Flag RFU Correctly") - def test_passkey_entry_iut_initiator_secure_connections_auth_req_rfu(self): - """ - Verify that the IUT supporting LE Secure Connections is able to perform the Passkey Entry pairing procedure when receiving additional bits set in the AuthReq flag. Reserved For Future Use bits are correctly handled when acting as central, initiator. - """ - self._prepare_cert_for_connection() - - self.dut.security.SetLeIoCapability(KEYBOARD_DISPLAY) - self.dut.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.dut_security.SetLeAuthRequirements(secure_connections=1) - - self.cert.security.SetLeIoCapability(KEYBOARD_ONLY) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert_security.SetLeAuthRequirements(mitm=1, secure_connections=1, reserved_bits=3) - - # 1. IUT transmits a Pairing Request command with: - # a. IO Capability set to “DisplayOnly” or “DisplayYesNo” or “KeyboardOnly” or “KeyboardDisplay” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. All reserved bits are set to ‘0’. - self.dut.security.CreateBondLe(self.cert_address) - - assertThat(self.cert_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.dut_address)) - - # 2. Lower Tester responds with a Pairing Response command, with: - # a. IO Capability set to “KeyboardOnly” - # b. OOB data flag set to 0x00 (OOB Authentication data not present) - # c. AuthReq bonding flag set to the value indicated in the IXIT [7] for ‘Bonding Flags’ and the MITM flag set to ‘1’ and all reserved bits are set to a random value. - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.dut_address)) - - assertThat(self.cert_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PASSKEY_ENTRY, self.dut_address)) - - passkey = self.dut_security.wait_for_ui_event_passkey() - - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PASSKEY, - numeric_value=passkey, - unique_id=1, - address=self.dut_address)) - - # 3. IUT and Lower Tester perform phase 2 of the Just Works pairing and establish an encrypted link with the generated LTK. - assertThat(self.dut_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BONDED, self.cert_address), - timeout=timedelta(seconds=10)) - - @metadata(pts_test_id="SM/MAS/SCOB/BV-01-C", - pts_test_name="Out of Band, IUT Initiator, Secure Connections – Success") - def test_out_of_band_iut_initiator_secure_connections(self): - """ - Verify that the IUT supporting LE Secure Connections performs the Out-of-Band pairing procedure correctly as central, initiator. - """ - - oob_combinations = [(OOB_NOT_PRESENT, OOB_PRESENT), (OOB_PRESENT, OOB_NOT_PRESENT), (OOB_PRESENT, OOB_PRESENT)] - - for (dut_oob_flag, cert_oob_flag) in oob_combinations: - print("oob flag combination dut: " + str(dut_oob_flag) + ", cert: " + str(cert_oob_flag)) - - self._prepare_cert_for_connection() - - if dut_oob_flag == LeOobDataFlag.PRESENT: - oobdata = self.cert.security.GetLeOutOfBandData(empty_proto.Empty()) - self.dut.security.SetOutOfBandData( - OobDataMessage(address=self.cert_address, - confirmation_value=oobdata.confirmation_value, - random_value=oobdata.random_value)) - - if cert_oob_flag == LeOobDataFlag.PRESENT: - oobdata = self.dut.security.GetLeOutOfBandData(empty_proto.Empty()) - self.cert.security.SetOutOfBandData( - OobDataMessage(address=self.dut_address, - confirmation_value=oobdata.confirmation_value, - random_value=oobdata.random_value)) - - self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) - self.dut.security.SetLeOobDataPresent(dut_oob_flag) - self.dut_security.SetLeAuthRequirements(bond=1, mitm=1, secure_connections=1) - - self.cert.security.SetLeIoCapability(DISPLAY_ONLY) - self.cert.security.SetLeOobDataPresent(cert_oob_flag) - self.cert_security.SetLeAuthRequirements(bond=1, mitm=1, secure_connections=1) - - # 1. IUT transmits a Pairing Request command with OOB data flag set to either 0x00 or 0x01, and Secure Connections flag set to '1'. - self.dut.security.CreateBondLe(self.cert_address) - - assertThat(self.cert_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.dut_address)) - - # 2. Lower Tester responds with a Pairing Response command with Secure Connections flag set to '1' and OOB data flag set to either 0x00 or 0x01. - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.dut_address)) - - # 3. IUT uses the 128-bit value generated by the Lower Tester as the confirm value. Similarly, the Lower Tester uses the 128-bit value generated by the IUT as the confirm value. - - # 4. IUT and Lower Tester perform phase 2 of the pairing process and establish an encrypted link with an LTK generated using the OOB data in phase 2. - assertThat(self.dut_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BONDED, self.cert_address), - timeout=timedelta(seconds=10)) - - assertThat(self.cert_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BONDED, self.dut_address), - timeout=timedelta(seconds=10)) - - self.dut.security.RemoveBond(self.cert_address) - self.cert.security.RemoveBond(self.dut_address) - - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_UNBONDED, self.cert_address)) - - self.dut_security.wait_device_disconnect(self.cert_address) - self.cert_security.wait_device_disconnect(self.dut_address) - - @metadata(pts_test_id="SM/SLA/SCOB/BV-02-C", - pts_test_name="Out of Band, IUT Responder, Secure Connections – Success") - def test_out_of_band_iut_responder_secure_connections(self): - """ - Verify that the IUT supporting LE Secure Connections is able to perform the Out-of-Band pairing procedure correctly when acting as peripheral, responder. - """ - - oob_combinations = [(OOB_NOT_PRESENT, OOB_PRESENT), (OOB_PRESENT, OOB_NOT_PRESENT), (OOB_PRESENT, OOB_PRESENT)] - - for (dut_oob_flag, cert_oob_flag) in oob_combinations: - print("oob flag combination dut: " + str(dut_oob_flag) + ", cert: " + str(cert_oob_flag)) - - self._prepare_dut_for_connection() - - if dut_oob_flag == LeOobDataFlag.PRESENT: - oobdata = self.cert.security.GetLeOutOfBandData(empty_proto.Empty()) - self.dut.security.SetOutOfBandData( - OobDataMessage(address=self.cert_address, - confirmation_value=oobdata.confirmation_value, - random_value=oobdata.random_value)) - - if cert_oob_flag == LeOobDataFlag.PRESENT: - oobdata = self.dut.security.GetLeOutOfBandData(empty_proto.Empty()) - self.cert.security.SetOutOfBandData( - OobDataMessage(address=self.dut_address, - confirmation_value=oobdata.confirmation_value, - random_value=oobdata.random_value)) - - self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) - self.dut.security.SetLeOobDataPresent(dut_oob_flag) - self.dut_security.SetLeAuthRequirements(bond=1, mitm=1, secure_connections=1) - - self.cert.security.SetLeIoCapability(DISPLAY_ONLY) - self.cert.security.SetLeOobDataPresent(cert_oob_flag) - self.cert_security.SetLeAuthRequirements(bond=1, mitm=1, secure_connections=1) - - # 1. Lower Tester transmits a Pairing Request command with OOB data flag set to either 0x00 or 0x01, and Secure Connections flag set to '1'. - self.cert.security.CreateBondLe(self.dut_address) - - assertThat(self.dut_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) - - # 2. IUT responds with a Pairing Response command with Secure Connections flag set to '1' and OOB data flag set to either 0x00 or 0x01. - self.dut.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.cert_address)) - - # 3. IUT uses the 128-bit value generated by the Lower Tester as the confirm value. Similarly, the Lower Tester uses the 128-bit value generated by the IUT as the confirm value. - - # 4. IUT and Lower Tester perform phase 2 of the pairing process and establish an encrypted link with an LTK generated using the OOB data in phase 2. - assertThat(self.cert_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BONDED, self.dut_address), - timeout=timedelta(seconds=10)) - - assertThat(self.dut_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BONDED, self.cert_address), - timeout=timedelta(seconds=10)) - - self.cert.security.RemoveBond(self.dut_address) - self.dut.security.RemoveBond(self.cert_address) - - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_UNBONDED, self.cert_address)) - - self.cert_security.wait_device_disconnect(self.dut_address) - self.dut_security.wait_device_disconnect(self.cert_address) - - @metadata(pts_test_id="SM/SLA/SCOB/BV-03-C", - pts_test_name="Out of Band, IUT Responder, Secure Connections – Handle AuthReq Flag RFU Correctly") - def test_out_of_band_iut_responder_secure_connections_auth_req_rfu(self): - """ - Verify that the IUT supporting LE Secure Connections is able to perform the Out-of-Band pairing procedure when receiving additional bits set in the AuthReq flag. Reserved For Future Use bits are correctly handled when acting as peripheral, responder. - """ - - reserved_bits_combinations = [1, 2, 3] - - for reserved_bits in reserved_bits_combinations: - print("reserved bits in cert dut: " + str(reserved_bits)) - - self._prepare_dut_for_connection() - - oobdata = self.cert.security.GetLeOutOfBandData(empty_proto.Empty()) - self.dut.security.SetOutOfBandData( - OobDataMessage(address=self.cert_address, - confirmation_value=oobdata.confirmation_value, - random_value=oobdata.random_value)) - - oobdata = self.dut.security.GetLeOutOfBandData(empty_proto.Empty()) - self.cert.security.SetOutOfBandData( - OobDataMessage(address=self.dut_address, - confirmation_value=oobdata.confirmation_value, - random_value=oobdata.random_value)) - - self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) - self.dut.security.SetLeOobDataPresent(OOB_PRESENT) - self.dut_security.SetLeAuthRequirements(bond=1, mitm=0, secure_connections=1) - - self.cert.security.SetLeIoCapability(DISPLAY_ONLY) - self.cert.security.SetLeOobDataPresent(OOB_PRESENT) - self.cert_security.SetLeAuthRequirements(bond=1, mitm=1, secure_connections=1, reserved_bits=reserved_bits) - - # 1. Lower Tester transmits Pairing Request command with: - # a. IO Capability set to any IO capability - # b. OOB data flag set to 0x01 (OOB Authentication data from remote device present) - # c. MITM set to ‘0’, Secure Connections flag is set to '1', and all reserved bits are set to a random value. - self.cert.security.CreateBondLe(self.dut_address) - - assertThat(self.dut_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.cert_address)) - - # 2. IUT responds with a Pairing Response command, with: - # a. IO Capability set to any IO capability - # b. OOB data flag set to 0x01 (OOB Authentication data present) - # c. Secure Connections flag is set to '1', All reserved bits are set to ‘0’ - self.dut.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.cert_address)) - - # 3. IUT and Lower Tester perform phase 2 of the OOB authenticated pairing and establish an encrypted link with the generated LTK. - - assertThat(self.cert_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BONDED, self.dut_address), - timeout=timedelta(seconds=10)) - - assertThat(self.dut_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BONDED, self.cert_address), - timeout=timedelta(seconds=10)) - - self.cert.security.RemoveBond(self.dut_address) - self.dut.security.RemoveBond(self.cert_address) - - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_UNBONDED, self.cert_address)) - - self.dut_security.wait_device_disconnect(self.cert_address) - self.cert_security.wait_device_disconnect(self.dut_address) - - @metadata(pts_test_id="SM/MAS/SCOB/BV-04-C", - pts_test_name="Out of Band, IUT Initiator, Secure Connections – Handle AuthReq Flag RFU Correctly") - def test_out_of_band_iut_initiator_secure_connections_auth_req_rfu(self): - """ - Verify that the IUT supporting LE Secure Connections is able to perform the Out-of-Band pairing procedure when receiving additional bits set in the AuthReq flag. Reserved For Future Use bits are correctly handled when acting as central, initiator. - """ - - reserved_bits_combinations = [1, 2, 3] - - for reserved_bits in reserved_bits_combinations: - print("reserved bits in cert dut: " + str(reserved_bits)) - - self._prepare_cert_for_connection() - - oobdata = self.cert.security.GetLeOutOfBandData(empty_proto.Empty()) - self.dut.security.SetOutOfBandData( - OobDataMessage(address=self.cert_address, - confirmation_value=oobdata.confirmation_value, - random_value=oobdata.random_value)) - - oobdata = self.dut.security.GetLeOutOfBandData(empty_proto.Empty()) - self.cert.security.SetOutOfBandData( - OobDataMessage(address=self.dut_address, - confirmation_value=oobdata.confirmation_value, - random_value=oobdata.random_value)) - - self.dut.security.SetLeIoCapability(KEYBOARD_ONLY) - self.dut.security.SetLeOobDataPresent(OOB_PRESENT) - self.dut_security.SetLeAuthRequirements(bond=1, mitm=0, secure_connections=1, reserved_bits=0) - - self.cert.security.SetLeIoCapability(DISPLAY_ONLY) - self.cert.security.SetLeOobDataPresent(OOB_PRESENT) - self.cert_security.SetLeAuthRequirements(bond=1, mitm=1, secure_connections=1, reserved_bits=reserved_bits) - - # 1. IUT transmits Pairing Request command with: - # a. IO Capability set to any IO capability - # b. OOB data flag set to 0x01 (OOB Authentication data present) - # c. MITM set to ‘0’, Secure Connections flag is set to '1', and all reserved bits are set to ‘0’ - self.dut.security.CreateBondLe(self.cert_address) - - assertThat(self.cert_security.get_ui_stream()).emits( - SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PAIRING_PROMPT, self.dut_address)) - - # 2. Lower Tester responds with a Pairing Response command, with: - # a. IO Capability set to any IO capability - # b. OOB data flag set to 0x01 (OOB Authentication data present) - # c. Secure Connections flag is set to '1', and all reserved bits are set to a random value. - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=self.dut_address)) - - # 3. IUT and Lower Tester perform phase 2 of the OOB authenticated pairing and establish an encrypted link with the generated LTK. - - assertThat(self.dut_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BONDED, self.cert_address), - timeout=timedelta(seconds=10)) - - assertThat(self.cert_security.get_bond_stream()).emits(SecurityMatchers.BondMsg( - BondMsgType.DEVICE_BONDED, self.dut_address), - timeout=timedelta(seconds=10)) - - self.dut.security.RemoveBond(self.cert_address) - self.cert.security.RemoveBond(self.dut_address) - - assertThat(self.dut_security.get_bond_stream()).emits( - SecurityMatchers.BondMsg(BondMsgType.DEVICE_UNBONDED, self.cert_address)) - - self.dut_security.wait_device_disconnect(self.cert_address) - self.cert_security.wait_device_disconnect(self.dut_address) - - -if __name__ == '__main__': - test_runner.main() diff --git a/system/blueberry/tests/gd/security/security_test.py b/system/blueberry/tests/gd/security/security_test.py deleted file mode 100644 index d8bcb19abf7..00000000000 --- a/system/blueberry/tests/gd/security/security_test.py +++ /dev/null @@ -1,552 +0,0 @@ -# -# Copyright 2019 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging - -from blueberry.tests.gd.cert.py_security import PySecurity -from blueberry.tests.gd.cert.truth import assertThat -from blueberry.tests.gd.cert import gd_base_test -from blueberry.tests.gd.security.cert_security import CertSecurity -from blueberry.facade import common_pb2 as common -from google.protobuf import empty_pb2 as empty_proto -from blueberry.facade.hci import controller_facade_pb2 as controller_facade -from blueberry.facade.hci import le_initiator_address_facade_pb2 as le_initiator_address_facade -from blueberry.facade.l2cap.classic.facade_pb2 import ClassicSecurityPolicy -from blueberry.facade.neighbor import facade_pb2 as neighbor_facade -from blueberry.facade.security.facade_pb2 import AuthenticationRequirements -from blueberry.facade.security.facade_pb2 import BondMsgType -from blueberry.facade.security.facade_pb2 import IoCapabilities -from blueberry.facade.security.facade_pb2 import OobDataPresent -from blueberry.facade.security.facade_pb2 import UiMsgType -from mobly import test_runner - - -class SecurityTest(gd_base_test.GdBaseTestClass): - """ - Collection of tests that each sample results from - different (unique) combinations of io capabilities, authentication requirements, and oob data. - """ - - _io_capabilities_name_lookup = { - IoCapabilities.DISPLAY_ONLY: "DISPLAY_ONLY", - IoCapabilities.DISPLAY_YES_NO_IO_CAP: "DISPLAY_YES_NO_IO_CAP", - #IoCapabilities.KEYBOARD_ONLY:"KEYBOARD_ONLY", - IoCapabilities.NO_INPUT_NO_OUTPUT: "NO_INPUT_NO_OUTPUT", - } - - _auth_reqs_name_lookup = { - AuthenticationRequirements.NO_BONDING: "NO_BONDING", - AuthenticationRequirements.NO_BONDING_MITM_PROTECTION: "NO_BONDING_MITM_PROTECTION", - AuthenticationRequirements.DEDICATED_BONDING: "DEDICATED_BONDING", - AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION: "DEDICATED_BONDING_MITM_PROTECTION", - AuthenticationRequirements.GENERAL_BONDING: "GENERAL_BONDING", - AuthenticationRequirements.GENERAL_BONDING_MITM_PROTECTION: "GENERAL_BONDING_MITM_PROTECTION", - } - - # Possible IO Capabilities - io_capabilities = ( - IoCapabilities.DISPLAY_ONLY, - IoCapabilities.DISPLAY_YES_NO_IO_CAP, - # TODO(optedoblivion): Uncomment when Passkey Entry is implemented in ClassicPairingHandler - #IoCapabilities.KEYBOARD_ONLY, - IoCapabilities.NO_INPUT_NO_OUTPUT) - - # Possible Authentication Requirements - auth_reqs = (AuthenticationRequirements.NO_BONDING, AuthenticationRequirements.NO_BONDING_MITM_PROTECTION, - AuthenticationRequirements.DEDICATED_BONDING, - AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION, - AuthenticationRequirements.GENERAL_BONDING, AuthenticationRequirements.GENERAL_BONDING_MITM_PROTECTION) - - # Possible Out-of-Band data options - oob_present = ( - OobDataPresent.NOT_PRESENT, - # TODO(optedoblivion): Uncomment when OOB is implemented in root canal - #"P192_PRESENT", - #"P256_PRESENT", - #"P192_AND_256_PRESENT" - ) - - mitm_auth_reqs = (AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION, - AuthenticationRequirements.GENERAL_BONDING_MITM_PROTECTION, - AuthenticationRequirements.NO_BONDING_MITM_PROTECTION) - - def setup_class(self): - gd_base_test.GdBaseTestClass.setup_class(self, dut_module='SECURITY', cert_module='L2CAP') - - def setup_test(self): - gd_base_test.GdBaseTestClass.setup_test(self) - - self.dut.neighbor.EnablePageScan(neighbor_facade.EnableMsg(enabled=True)) - self.cert.neighbor.EnablePageScan(neighbor_facade.EnableMsg(enabled=True)) - - self.dut.name = b'DUT Device' - self.dut.address = self.dut.hci_controller.GetMacAddress(empty_proto.Empty()).address - self.cert.name = b'Cert Device' - self.cert.address = self.cert.hci_controller.GetMacAddress(empty_proto.Empty()).address - - # TODO(optedoblivion): Make this happen in PySecurity or GdDevice - self.dut.hci_controller.WriteLocalName(controller_facade.NameMsg(name=self.dut.name)) - self.cert.hci_controller.WriteLocalName(controller_facade.NameMsg(name=self.cert.name)) - - self.dut_security = PySecurity(self.dut) - self.cert_security = CertSecurity(self.cert) - - self.dut_address = common.BluetoothAddressWithType( - address=common.BluetoothAddress(address=bytes(b'DD:05:04:03:02:01')), type=common.RANDOM_DEVICE_ADDRESS) - privacy_policy = le_initiator_address_facade.PrivacyPolicy( - address_policy=le_initiator_address_facade.AddressPolicy.USE_STATIC_ADDRESS, - address_with_type=self.dut_address) - self.dut.security.SetLeInitiatorAddressPolicy(privacy_policy) - - def teardown_test(self): - self.dut_security.close() - self.cert_security.close() - gd_base_test.GdBaseTestClass.teardown_test(self) - - # Initiates the numeric comparison test - def _run_ssp_numeric_comparison(self, initiator, responder, init_ui_response, resp_ui_response, - expected_init_ui_event, expected_resp_ui_event, expected_init_bond_event, - expected_resp_bond_event): - initiator.enable_secure_simple_pairing() - responder.enable_secure_simple_pairing() - initiator.create_bond(responder.get_address(), common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - self._verify_ssp_numeric_comparison(initiator, responder, init_ui_response, resp_ui_response, - expected_init_ui_event, expected_resp_ui_event, expected_init_bond_event, - expected_resp_bond_event) - - # Verifies the events for the numeric comparion test - def _verify_ssp_numeric_comparison(self, initiator, responder, init_ui_response, resp_ui_response, - expected_init_ui_event, expected_resp_ui_event, expected_init_bond_event, - expected_resp_bond_event): - - def on_responder_reply(): - initiator.on_user_input(responder.get_address(), init_ui_response, expected_init_ui_event) - - responder.accept_pairing(initiator.get_address(), resp_ui_response, init_ui_response, on_responder_reply) - initiator.wait_for_bond_event(expected_init_bond_event) - responder.wait_for_bond_event(expected_resp_bond_event) - - def _run_ssp_oob(self, initiator, responder, init_ui_response, resp_ui_response, expected_init_ui_event, - expected_resp_ui_event, expected_init_bond_event, expected_resp_bond_event, p192_oob_data, - p256_oob_data): - initiator.enable_secure_simple_pairing() - responder.enable_secure_simple_pairing() - initiator.create_bond_out_of_band(responder.get_address(), - common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS, p192_oob_data, - p256_oob_data) - self._verify_ssp_oob(initiator, responder, init_ui_response, resp_ui_response, expected_init_ui_event, - expected_resp_ui_event, expected_init_bond_event, expected_resp_bond_event, p192_oob_data, - p256_oob_data) - - # Verifies the events for the numeric comparion test - def _verify_ssp_oob(self, initiator, responder, init_ui_response, resp_ui_response, expected_init_ui_event, - expected_resp_ui_event, expected_init_bond_event, expected_resp_bond_event, p192_oob_data, - p256_oob_data): - responder.accept_oob_pairing(initiator.get_address()) - initiator.on_user_input(responder.get_address(), init_ui_response, expected_init_ui_event) - initiator.wait_for_bond_event(expected_init_bond_event) - responder.wait_for_bond_event(expected_resp_bond_event) - - def _run_ssp_passkey(self, initiator, responder, expected_init_bond_event, expected_resp_bond_event): - initiator.enable_secure_simple_pairing() - responder.enable_secure_simple_pairing() - initiator.create_bond(responder.get_address(), common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - self._verify_ssp_passkey(initiator, responder, expected_init_bond_event, expected_resp_bond_event) - - def _verify_ssp_passkey(self, initiator, responder, expected_init_bond_event, expected_resp_bond_event): - responder.send_io_caps(initiator.get_address()) - passkey = initiator.wait_for_passkey(responder.get_address()) - responder.input_passkey(initiator.get_address(), passkey) - initiator.wait_for_bond_event(expected_init_bond_event) - responder.wait_for_bond_event(expected_resp_bond_event) - - def _run_pin(self, initiator, responder, expected_init_bond_event, expected_resp_bond_event): - initiator.create_bond(responder.get_address(), common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - self._verify_pin(initiator, responder, expected_init_bond_event, expected_resp_bond_event) - - def _verify_pin(self, initiator, responder, expected_init_bond_event, expected_resp_bond_event): - pin = b'123456789A' - logging.info("pin: %s" % pin) - initiator.input_pin(responder.get_address(), pin) - responder.input_pin(initiator.get_address(), pin) - initiator.wait_for_bond_event(expected_init_bond_event) - responder.wait_for_bond_event(expected_resp_bond_event) - - def test_setup_teardown(self): - """ - Make sure our setup and teardown is sane - """ - pass - - # no_input_no_output + no_input_no_output is JustWorks no confirmation - def test_dut_initiated_no_input_no_output_no_input_no_output_twice_bond_and_enforce(self): - # Arrange - self.dut_security.set_io_capabilities(IoCapabilities.NO_INPUT_NO_OUTPUT) - self.dut_security.set_authentication_requirements(AuthenticationRequirements.DEDICATED_BONDING) - self.cert_security.set_io_capabilities(IoCapabilities.NO_INPUT_NO_OUTPUT) - self.cert_security.set_authentication_requirements(AuthenticationRequirements.DEDICATED_BONDING) - - # Act and Assert - self._run_ssp_numeric_comparison( - initiator=self.dut_security, - responder=self.cert_security, - init_ui_response=True, - resp_ui_response=True, - expected_init_ui_event=None, - expected_resp_ui_event=None, - expected_init_bond_event=BondMsgType.DEVICE_BONDED, - expected_resp_bond_event=None) - - self.dut_security.enforce_security_policy(self.cert.address, - common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS, - ClassicSecurityPolicy.ENCRYPTED_TRANSPORT) - - # TODO: We verify enforcement when we make sure EncryptionChange is received on DUT - - # no_input_no_output + no_input_no_output is JustWorks no confirmation - def test_dut_initiated_no_input_no_output_no_input_no_output_twice_with_remove_bond(self): - # Arrange - self.dut_security.set_io_capabilities(IoCapabilities.NO_INPUT_NO_OUTPUT) - self.dut_security.set_authentication_requirements(AuthenticationRequirements.DEDICATED_BONDING) - self.cert_security.set_io_capabilities(IoCapabilities.NO_INPUT_NO_OUTPUT) - self.cert_security.set_authentication_requirements(AuthenticationRequirements.DEDICATED_BONDING) - - # Act and Assert - self._run_ssp_numeric_comparison( - initiator=self.dut_security, - responder=self.cert_security, - init_ui_response=True, - resp_ui_response=True, - expected_init_ui_event=None, - expected_resp_ui_event=None, - expected_init_bond_event=BondMsgType.DEVICE_BONDED, - expected_resp_bond_event=None) - - self.dut_security.remove_bond(self.cert.address, common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - self.cert_security.remove_bond(self.cert.address, common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - self.dut_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) - self.cert_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) - - self.dut_security.wait_for_disconnect_event() - self.cert_security.wait_for_disconnect_event() - - # Act and Assert - self._run_ssp_numeric_comparison( - initiator=self.dut_security, - responder=self.cert_security, - init_ui_response=True, - resp_ui_response=True, - expected_init_ui_event=None, - expected_resp_ui_event=None, - expected_init_bond_event=BondMsgType.DEVICE_BONDED, - expected_resp_bond_event=None) - - self.dut_security.remove_bond(self.cert.address, common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - self.cert_security.remove_bond(self.cert.address, common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - self.dut_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) - self.cert_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) - - self.dut_security.wait_for_disconnect_event() - self.cert_security.wait_for_disconnect_event() - - def test_successful_dut_initiated_ssp_numeric_comparison(self): - test_count = len(self.io_capabilities) * len(self.auth_reqs) * len(self.oob_present) * len( - self.io_capabilities) * len(self.auth_reqs) * len(self.oob_present) - logging.info("Loading %d test combinations" % test_count) - i = 0 - for dut_io_capability in self.io_capabilities: - for dut_auth_reqs in self.auth_reqs: - for dut_oob_present in self.oob_present: - for cert_io_capability in self.io_capabilities: - for cert_auth_reqs in self.auth_reqs: - for cert_oob_present in self.oob_present: - i = i + 1 - logging.info("") - logging.info("===================================================") - logging.info("Running test %d of %d" % (i, test_count)) - logging.info("DUT Test Config: %s ; %s ; %s " % (self._io_capabilities_name_lookup.get( - dut_io_capability, "ERROR"), self._auth_reqs_name_lookup.get( - dut_auth_reqs, "ERROR"), dut_oob_present)) - logging.info( - "CERT Test Config: %s ; %s ; %s " % - (self._io_capabilities_name_lookup.get(cert_io_capability, "ERROR"), - self._auth_reqs_name_lookup.get(cert_auth_reqs, "ERROR"), cert_oob_present)) - logging.info("===================================================") - logging.info("") - self.dut_security.set_io_capabilities(dut_io_capability) - self.dut_security.set_authentication_requirements(dut_auth_reqs) - self.cert_security.set_io_capabilities(cert_io_capability) - self.cert_security.set_authentication_requirements(cert_auth_reqs) - init_ui_response = True - resp_ui_response = True - expected_init_ui_event = None # None is auto accept - expected_resp_ui_event = None # None is auto accept - expected_init_bond_event = BondMsgType.DEVICE_BONDED - expected_resp_bond_event = None - if dut_io_capability == IoCapabilities.DISPLAY_ONLY: - if cert_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: - expected_resp_ui_event = UiMsgType.DISPLAY_YES_NO_WITH_VALUE - if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: - expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED - elif cert_io_capability == IoCapabilities.KEYBOARD_ONLY: - expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY - elif cert_io_capability == IoCapabilities.DISPLAY_ONLY: - if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: - expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED - elif cert_io_capability == IoCapabilities.NO_INPUT_NO_OUTPUT: - if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: - expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED - elif dut_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: - expected_init_ui_event = UiMsgType.DISPLAY_YES_NO_WITH_VALUE - if cert_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: - expected_resp_ui_event = UiMsgType.DISPLAY_YES_NO_WITH_VALUE - elif cert_io_capability == IoCapabilities.KEYBOARD_ONLY: - expected_init_ui_event = UiMsgType.DISPLAY_PASSKEY - expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY - elif cert_io_capability == IoCapabilities.NO_INPUT_NO_OUTPUT: - expected_init_ui_event = UiMsgType.DISPLAY_YES_NO # No value - elif dut_io_capability == IoCapabilities.KEYBOARD_ONLY: - expected_init_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY - if cert_io_capability == IoCapabilities.DISPLAY_ONLY: - expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY - elif cert_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: - expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY - elif cert_io_capability == IoCapabilities.KEYBOARD_ONLY: - expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY - elif cert_io_capability == IoCapabilities.NO_INPUT_NO_OUTPUT: - if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: - expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED - elif dut_io_capability == IoCapabilities.NO_INPUT_NO_OUTPUT: - if cert_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: - expected_resp_ui_event = UiMsgType.DISPLAY_YES_NO # No value - - if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: - expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED - - if cert_oob_present == OobDataPresent.NOT_PRESENT: - self._run_ssp_numeric_comparison( - initiator=self.dut_security, - responder=self.cert_security, - init_ui_response=init_ui_response, - resp_ui_response=resp_ui_response, - expected_init_ui_event=expected_init_ui_event, - expected_resp_ui_event=expected_resp_ui_event, - expected_init_bond_event=expected_init_bond_event, - expected_resp_bond_event=expected_resp_bond_event) - else: - logging.error("Code path not yet implemented") - assertThat(False).isTrue() - - self.dut_security.remove_bond(self.cert_security.get_address(), - common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - self.cert_security.remove_bond(self.dut_security.get_address(), - common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - - self.dut_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) - self.cert_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) - - self.dut_security.wait_for_disconnect_event() - self.cert_security.wait_for_disconnect_event() - - def test_enable_secure_simple_pairing(self): - self.dut_security.enable_secure_simple_pairing() - self.cert_security.enable_secure_simple_pairing() - - def test_enable_secure_connections(self): - self.dut_security.enable_secure_simple_pairing() - self.cert_security.enable_secure_simple_pairing() - self.dut_security.enable_secure_connections() - self.cert_security.enable_secure_connections() - - def test_get_oob_data_from_dut_controller_p192_present(self): - oob_data = self.dut_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) - assertThat(len(oob_data)).isEqualTo(4) - has192C = not all([i == 0 for i in oob_data[0]]) - has192R = not all([i == 0 for i in oob_data[1]]) - has256C = not all([i == 0 for i in oob_data[2]]) - has256R = not all([i == 0 for i in oob_data[3]]) - assertThat(has192C).isTrue() - assertThat(has192R).isTrue() - assertThat(has256C).isFalse() - assertThat(has256R).isFalse() - - def test_get_oob_data_from_cert_controller_not_present(self): - oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.NOT_PRESENT) - assertThat(len(oob_data)).isEqualTo(4) - has192C = not all([i == 0 for i in oob_data[0]]) - has192R = not all([i == 0 for i in oob_data[1]]) - has256C = not all([i == 0 for i in oob_data[2]]) - has256R = not all([i == 0 for i in oob_data[3]]) - assertThat(has192C).isFalse() - assertThat(has192R).isFalse() - assertThat(has256C).isFalse() - assertThat(has256R).isFalse() - - def test_get_oob_data_from_cert_controller_p192_present_no_secure_connections(self): - oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) - assertThat(len(oob_data)).isEqualTo(4) - has192C = not all([i == 0 for i in oob_data[0]]) - has192R = not all([i == 0 for i in oob_data[1]]) - has256C = not all([i == 0 for i in oob_data[2]]) - has256R = not all([i == 0 for i in oob_data[3]]) - assertThat(has192C).isTrue() - assertThat(has192R).isTrue() - assertThat(has256C).isFalse() - assertThat(has256R).isFalse() - - def test_get_oob_data_from_cert_controller_p192_present(self): - self.cert_security.enable_secure_simple_pairing() - self.cert_security.enable_secure_connections() - oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) - assertThat(len(oob_data)).isEqualTo(4) - has192C = not all([i == 0 for i in oob_data[0]]) - has192R = not all([i == 0 for i in oob_data[1]]) - has256C = not all([i == 0 for i in oob_data[2]]) - has256R = not all([i == 0 for i in oob_data[3]]) - assertThat(has192C).isTrue() - assertThat(has192R).isTrue() - assertThat(has256C).isFalse() - assertThat(has256R).isFalse() - - def test_get_oob_data_from_cert_controller_p256_present(self): - self.cert_security.enable_secure_simple_pairing() - self.cert_security.enable_secure_connections() - oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P256_PRESENT) - assertThat(len(oob_data)).isEqualTo(4) - has192C = not all([i == 0 for i in oob_data[0]]) - has192R = not all([i == 0 for i in oob_data[1]]) - has256C = not all([i == 0 for i in oob_data[2]]) - has256R = not all([i == 0 for i in oob_data[3]]) - assertThat(has192C).isFalse() - assertThat(has192R).isFalse() - assertThat(has256C).isTrue() - assertThat(has256R).isTrue() - - def test_get_oob_data_from_cert_controller_p192_and_p256_present(self): - self.cert_security.enable_secure_simple_pairing() - self.cert_security.enable_secure_connections() - oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P192_AND_256_PRESENT) - assertThat(len(oob_data)).isEqualTo(4) - has192C = not all([i == 0 for i in oob_data[0]]) - has192R = not all([i == 0 for i in oob_data[1]]) - has256C = not all([i == 0 for i in oob_data[2]]) - has256R = not all([i == 0 for i in oob_data[3]]) - assertThat(has192C).isTrue() - assertThat(has192R).isTrue() - assertThat(has256C).isTrue() - assertThat(has256R).isTrue() - - def test_successful_dut_initiated_ssp_oob(self): - dut_io_capability = IoCapabilities.NO_INPUT_NO_OUTPUT - cert_io_capability = IoCapabilities.NO_INPUT_NO_OUTPUT - dut_auth_reqs = AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION - cert_auth_reqs = AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION - cert_oob_present = OobDataPresent.P192_PRESENT - self.dut_security.enable_secure_simple_pairing() - self.dut_security.enable_secure_connections() - self.cert_security.enable_secure_simple_pairing() - self.cert_security.enable_secure_connections() - self.dut_security.set_io_capabilities(dut_io_capability) - self.dut_security.set_authentication_requirements(dut_auth_reqs) - self.cert_security.set_io_capabilities(cert_io_capability) - self.cert_security.set_authentication_requirements(cert_auth_reqs) - init_ui_response = True - resp_ui_response = True - expected_init_ui_event = None # None is auto accept - expected_resp_ui_event = None # None is auto accept - expected_init_bond_event = BondMsgType.DEVICE_BONDED - expected_resp_bond_event = None - # get_oob_data returns a tuple of bytes (p192c,p192r,p256c,p256r) - local_oob_data = self.cert_security.get_oob_data_from_controller(cert_oob_present) - p192_oob_data = local_oob_data[0:2] - p256_oob_data = local_oob_data[2:4] - self._run_ssp_oob( - initiator=self.dut_security, - responder=self.cert_security, - init_ui_response=init_ui_response, - resp_ui_response=resp_ui_response, - expected_init_ui_event=expected_init_ui_event, - expected_resp_ui_event=expected_resp_ui_event, - expected_init_bond_event=expected_init_bond_event, - expected_resp_bond_event=expected_resp_bond_event, - p192_oob_data=p192_oob_data, - p256_oob_data=p256_oob_data) - self.dut_security.remove_bond(self.cert_security.get_address(), - common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - self.cert_security.remove_bond(self.dut_security.get_address(), - common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - self.dut_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) - self.cert_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) - self.dut_security.wait_for_disconnect_event() - self.cert_security.wait_for_disconnect_event() - - def test_successful_dut_initiated_ssp_keyboard(self): - dut_io_capability = IoCapabilities.DISPLAY_YES_NO_IO_CAP - dut_auth_reqs = AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION - dut_oob_present = OobDataPresent.NOT_PRESENT - cert_io_capability = IoCapabilities.KEYBOARD_ONLY - cert_auth_reqs = AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION - cert_oob_present = OobDataPresent.NOT_PRESENT - self.dut_security.set_io_capabilities(dut_io_capability) - self.dut_security.set_authentication_requirements(dut_auth_reqs) - self.cert_security.set_io_capabilities(cert_io_capability) - self.cert_security.set_authentication_requirements(cert_auth_reqs) - - self._run_ssp_passkey( - initiator=self.dut_security, - responder=self.cert_security, - expected_init_bond_event=BondMsgType.DEVICE_BONDED, - expected_resp_bond_event=BondMsgType.DEVICE_BONDED) - - self.dut_security.remove_bond(self.cert_security.get_address(), - common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - self.cert_security.remove_bond(self.dut_security.get_address(), - common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - - self.dut_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) - self.cert_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) - - self.dut_security.wait_for_disconnect_event() - self.cert_security.wait_for_disconnect_event() - - def test_successful_dut_initiated_pin(self): - self.dut_security.set_io_capabilities(IoCapabilities.DISPLAY_YES_NO_IO_CAP) - self.dut_security.set_authentication_requirements(AuthenticationRequirements.DEDICATED_BONDING) - - self._run_pin( - initiator=self.dut_security, - responder=self.cert_security, - expected_init_bond_event=BondMsgType.DEVICE_BONDED, - expected_resp_bond_event=BondMsgType.DEVICE_BONDED) - - self.dut_security.remove_bond(self.cert_security.get_address(), - common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - self.cert_security.remove_bond(self.dut_security.get_address(), - common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) - - self.dut_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) - self.cert_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) - - self.dut_security.wait_for_disconnect_event() - self.cert_security.wait_for_disconnect_event() - - def test_make_sure_oob_data_different(self): - oob_data = self.dut_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) - oob_data2 = self.dut_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) - assertThat(oob_data).isNotEqualTo(oob_data2) - - -if __name__ == '__main__': - test_runner.main() -- GitLab From e9d9e863e93879a16f8b9f6a61c1a16b24ad9482 Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Wed, 22 May 2024 00:33:01 +0000 Subject: [PATCH 0006/1446] a2dp: Implement first a2dp avatar test Bug: 34554257 Test: avatar run --mobly-std-log --include-filter 'A2dpTest' Flag: EXEMPT, test change Change-Id: I82bd0e43398ae6cdeedee28723199fcc0061141c --- android/pandora/server/src/A2dp.kt | 7 + android/pandora/test/a2dp_test.py | 257 +++++++++++++++++++++++++++++ android/pandora/test/main.py | 7 +- 3 files changed, 269 insertions(+), 2 deletions(-) create mode 100644 android/pandora/test/a2dp_test.py diff --git a/android/pandora/server/src/A2dp.kt b/android/pandora/server/src/A2dp.kt index bff8c0eb5cb..59fe71b5264 100644 --- a/android/pandora/server/src/A2dp.kt +++ b/android/pandora/server/src/A2dp.kt @@ -161,6 +161,11 @@ class A2dp(val context: Context) : A2DPImplBase(), Closeable { throw RuntimeException("Device is not connected, cannot start") } + // Configure the selected device as active device if it is not + // already. + bluetoothA2dp.setActiveDevice(device) + + // Play an audio track. audioTrack!!.play() // If A2dp is not already playing, wait for it @@ -281,6 +286,7 @@ class A2dp(val context: Context) : A2DPImplBase(), Closeable { ) } } + override fun onError(t: Throwable) { t.printStackTrace() val sw = StringWriter() @@ -289,6 +295,7 @@ class A2dp(val context: Context) : A2DPImplBase(), Closeable { Status.UNKNOWN.withCause(t).withDescription(sw.toString()).asException() ) } + override fun onCompleted() { responseObserver.onNext(PlaybackAudioResponse.getDefaultInstance()) responseObserver.onCompleted() diff --git a/android/pandora/test/a2dp_test.py b/android/pandora/test/a2dp_test.py new file mode 100644 index 00000000000..4feb5067d7c --- /dev/null +++ b/android/pandora/test/a2dp_test.py @@ -0,0 +1,257 @@ +# Copyright 2023 Google LLC +# +# 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 +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import asyncio +import avatar +import itertools +import logging +import math +import numpy as np +import os + +from avatar import BumblePandoraDevice, PandoraDevice, PandoraDevices +from bumble import avdtp +from bumble.a2dp import ( + A2DP_SBC_CODEC_TYPE, + SBC_DUAL_CHANNEL_MODE, + SBC_JOINT_STEREO_CHANNEL_MODE, + SBC_LOUDNESS_ALLOCATION_METHOD, + SBC_MONO_CHANNEL_MODE, + SBC_SNR_ALLOCATION_METHOD, + SBC_STEREO_CHANNEL_MODE, + SbcMediaCodecInformation, + make_audio_sink_service_sdp_records, +) +from bumble.avdtp import ( + AVDTP_AUDIO_MEDIA_TYPE, + AVDTP_OPEN_STATE, + AVDTP_STREAMING_STATE, + Listener, + MediaCodecCapabilities, +) +from bumble.pairing import PairingDelegate +from mobly import base_test, test_runner +from mobly.asserts import assert_equal # type: ignore +from mobly.asserts import assert_in # type: ignore +from mobly.asserts import assert_is_none # type: ignore +from mobly.asserts import assert_is_not_none # type: ignore +from mobly.asserts import fail # type: ignore +from pandora.a2dp_grpc_aio import A2DP +from pandora.a2dp_pb2 import PlaybackAudioRequest, Sink, Source +from pandora.host_pb2 import Connection +from pandora.security_pb2 import LEVEL2 +from threading import Thread +from typing import Optional + + +async def initiate_pairing(device, address) -> Connection: + """Connect and pair a remote device.""" + + result = await device.aio.host.Connect(address=address) + connection = result.connection + assert connection + + bond = await device.aio.security.Secure(connection=connection, classic=LEVEL2) + assert bond.success + + return connection + + +async def accept_pairing(device, address) -> Connection: + """Accept connection and pairing from a remote device.""" + + result = await device.aio.host.WaitConnection(address=address) + connection = result.connection + assert connection + + bond = await device.aio.security.WaitSecurity(connection=connection, classic=LEVEL2) + assert bond.success + + return connection + + +async def open_source(device, connection) -> Source: + """Initiate AVDTP connection from Android device.""" + + result = await device.a2dp.OpenSource(connection=connection) + source = result.source + assert source + + return source + + +def codec_capabilities(): + """Codec capabilities for the Bumble sink devices.""" + + return MediaCodecCapabilities( + media_type=AVDTP_AUDIO_MEDIA_TYPE, + media_codec_type=A2DP_SBC_CODEC_TYPE, + media_codec_information=SbcMediaCodecInformation.from_lists( + sampling_frequencies=[48000, 44100, 32000, 16000], + channel_modes=[ + SBC_MONO_CHANNEL_MODE, + SBC_DUAL_CHANNEL_MODE, + SBC_STEREO_CHANNEL_MODE, + SBC_JOINT_STEREO_CHANNEL_MODE, + ], + block_lengths=[4, 8, 12, 16], + subbands=[4, 8], + allocation_methods=[ + SBC_LOUDNESS_ALLOCATION_METHOD, + SBC_SNR_ALLOCATION_METHOD, + ], + minimum_bitpool_value=2, + maximum_bitpool_value=53, + ), + ) + + +class AudioSignal: + """Audio signal generator and verifier.""" + + SINE_FREQUENCY = 440 + SINE_DURATION = 0.1 + + def __init__(self, a2dp: A2DP, source: Source, amplitude, fs): + """Init AudioSignal class. + + Args: + a2dp: A2DP profile interface. + source: Source connection object to send the data to. + amplitude: amplitude of the signal to generate. + fs: sampling rate of the signal to generate. + """ + self.a2dp = a2dp + self.source = source + self.amplitude = amplitude + self.fs = fs + self.task = None + + def start(self): + """Generates the audio signal and send it to the transport.""" + self.task = asyncio.create_task(self._run()) + + async def _run(self): + sine = self._generate_sine(self.SINE_FREQUENCY, self.SINE_DURATION) + + # Interleaved audio. + stereo = np.zeros(sine.size * 2, dtype=sine.dtype) + stereo[0::2] = sine + + # Send 4 second of audio. + audio = itertools.repeat(stereo.tobytes(), int(4 / self.SINE_DURATION)) + + for frame in audio: + await self.a2dp.PlaybackAudio(PlaybackAudioRequest(data=frame, source=self.source)) + + def _generate_sine(self, f, duration): + sine = self.amplitude * np.sin(2 * np.pi * np.arange(self.fs * duration) * (f / self.fs)) + s16le = (sine * 32767).astype(' None: + self.devices = PandoraDevices(self) + self.dut, self.ref1, self.ref2, *_ = self.devices + + if not isinstance(self.ref1, BumblePandoraDevice): + raise signals.TestAbortClass('Test require Bumble as reference device(s)') + if not isinstance(self.ref2, BumblePandoraDevice): + raise signals.TestAbortClass('Test require Bumble as reference device(s)') + + # Enable BR/EDR mode and SSP for Bumble devices. + for device in self.devices: + if isinstance(device, BumblePandoraDevice): + device.config.setdefault('classic_enabled', True) + device.config.setdefault('classic_ssp_enabled', True) + device.config.setdefault('classic_smp_enabled', False) + device.server_config.io_capability = PairingDelegate.NO_OUTPUT_NO_INPUT + + await asyncio.gather(self.dut.reset(), self.ref1.reset(), self.ref2.reset()) + + self.dut.a2dp = A2DP(channel=self.dut.aio.channel) + + handle = 0x00010001 + self.ref1.device.sdp_service_records = {handle: make_audio_sink_service_sdp_records(handle)} + self.ref2.device.sdp_service_records = {handle: make_audio_sink_service_sdp_records(handle)} + + self.ref1.a2dp = Listener.for_device(self.ref1.device) + self.ref2.a2dp = Listener.for_device(self.ref2.device) + self.ref1.a2dp_sink = None + self.ref2.a2dp_sink = None + + def on_ref1_avdtp_connection(server): + self.ref1.a2dp_sink = server.add_sink(codec_capabilities()) + + def on_ref2_avdtp_connection(server): + self.ref2.a2dp_sink = server.add_sink(codec_capabilities()) + + self.ref1.a2dp.on('connection', on_ref1_avdtp_connection) + self.ref2.a2dp.on('connection', on_ref2_avdtp_connection) + + def teardown_class(self) -> None: + if self.devices: + self.devices.stop_all() + + @avatar.asynchronous + async def setup_test(self) -> None: + pass + + @avatar.asynchronous + async def test_connect_and_stream(self) -> None: + """Basic A2DP connection and streaming test. + This test wants to be a template to be reused for other tests. + + 1. Pair and Connect RD1 + 2. Start streaming + 3. Check AVDTP status on RD1 + 4. Stop streaming + 5. Check AVDTP status on RD1 + """ + # Connect and pair RD1. + dut_ref1, ref1_dut = await asyncio.gather( + initiate_pairing(self.dut, self.ref1.address), + accept_pairing(self.ref1, self.dut.address), + ) + + # Connect AVDTP to RD1. + dut_ref1_source = await open_source(self.dut, dut_ref1) + assert_is_not_none(self.ref1.a2dp_sink) + assert_is_not_none(self.ref1.a2dp_sink.stream) + assert_in(self.ref1.a2dp_sink.stream.state, [AVDTP_OPEN_STATE, AVDTP_STREAMING_STATE]) + + # Start streaming to RD1. + await self.dut.a2dp.Start(source=dut_ref1_source) + audio = AudioSignal(self.dut.a2dp, dut_ref1_source, 0.8, 44100) + assert_equal(self.ref1.a2dp_sink.stream.state, AVDTP_STREAMING_STATE) + + # Stop streaming to RD1. + await self.dut.a2dp.Suspend(source=dut_ref1_source) + assert_equal(self.ref1.a2dp_sink.stream.state, AVDTP_OPEN_STATE) + + +if __name__ == '__main__': + logging.basicConfig(level=logging.DEBUG) + test_runner.main() # type: ignore diff --git a/android/pandora/test/main.py b/android/pandora/test/main.py index 6c02b26410b..af990f80c02 100644 --- a/android/pandora/test/main.py +++ b/android/pandora/test/main.py @@ -13,6 +13,8 @@ from typing import List, Tuple _BUMBLE_BTSNOOP_FMT = 'bumble_btsnoop_{pid}_{instance}.log' +import a2dp_test + # Import test cases modules. import asha_test import avatar.cases.host_test @@ -21,14 +23,15 @@ import avatar.cases.le_security_test import avatar.cases.security_test import gatt_test import hfpclient_test -import sdp_test import pairing.smp_test as smp_test +import sdp_test _TEST_CLASSES_LIST = [ avatar.cases.host_test.HostTest, avatar.cases.le_host_test.LeHostTest, avatar.cases.security_test.SecurityTest, avatar.cases.le_security_test.LeSecurityTest, + a2dp_test.A2dpTest, sdp_test.SdpTest, smp_test.SmpTest, gatt_test.GattTest, @@ -49,7 +52,7 @@ if __name__ == "__main__": # This is a hack for `tradefed` because of `b/166468397`. if '--' in sys.argv: index = sys.argv.index('--') - sys.argv = sys.argv[:1] + sys.argv[index + 1:] + sys.argv = sys.argv[:1] + sys.argv[index + 1 :] # Enable bumble snoop logger. ns, argv = _parse_cli_args() -- GitLab From facf11fbe0adfa7e41278e9febd0a8c791987c88 Mon Sep 17 00:00:00 2001 From: Kyunglyul Hyun Date: Tue, 11 Jun 2024 08:26:08 +0000 Subject: [PATCH 0007/1446] Fix potential NPE in SapService It could throw NPE if mService is being cleaned up while accessing the variable. This also fixes SapServiceTest failed in the local enviornment. Flag: EXEMPT, strict null check Bug: 339695797 Test: atest SapServiceTest Change-Id: Ib2b09cad6ff84f41e66f07cfb066bc33e3ad1c0c --- .../app/src/com/android/bluetooth/sap/SapService.java | 10 ++++++---- .../src/com/android/bluetooth/sap/SapServiceTest.java | 6 ++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/android/app/src/com/android/bluetooth/sap/SapService.java b/android/app/src/com/android/bluetooth/sap/SapService.java index 24caab0c747..31e8ab374fd 100644 --- a/android/app/src/com/android/bluetooth/sap/SapService.java +++ b/android/app/src/com/android/bluetooth/sap/SapService.java @@ -907,12 +907,14 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) private SapService getService(AttributionSource source) { - if (!Utils.checkServiceAvailable(mService, TAG) - || !Utils.checkCallerIsSystemOrActiveOrManagedUser(mService, TAG) - || !Utils.checkConnectPermissionForDataDelivery(mService, source, TAG)) { + SapService sapService = mService; + + if (!Utils.checkServiceAvailable(sapService, TAG) + || !Utils.checkCallerIsSystemOrActiveOrManagedUser(sapService, TAG) + || !Utils.checkConnectPermissionForDataDelivery(sapService, source, TAG)) { return null; } - return mService; + return sapService; } SapBinder(SapService service) { diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java index 33972dcb8b4..84bf6f36524 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java @@ -25,6 +25,7 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.content.Intent; +import android.os.Looper; import androidx.test.filters.MediumTest; import androidx.test.platform.app.InstrumentationRegistry; @@ -62,6 +63,11 @@ public class SapServiceTest { public void setUp() throws Exception { mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); TestUtils.setAdapterService(mAdapterService); + + if (Looper.myLooper() == null) { + Looper.prepare(); + } + mService = new SapService(mTargetContext); mService.start(); mService.setAvailable(true); -- GitLab From ccc66f436a4877963f80736b793e1745de7c546e Mon Sep 17 00:00:00 2001 From: William Escande Date: Tue, 11 Jun 2024 14:30:24 -0700 Subject: [PATCH 0008/1446] AutoOnFeature: Prevent double metric log The metric is reported unconditionally of the settings being already on This change prevent to report double trigger of the feature Bug: 311772251 Bug: 323060869 Test: None Flag: com.android.bluetooth.flags.auto_on_feature Change-Id: Id851b880f8c39936850f42484ecd0a6661101506 --- service/src/AutoOnFeature.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/service/src/AutoOnFeature.kt b/service/src/AutoOnFeature.kt index 6181e3df6ce..4c1fb93474f 100644 --- a/service/src/AutoOnFeature.kt +++ b/service/src/AutoOnFeature.kt @@ -136,6 +136,10 @@ public fun setUserEnabled( if (!isUserSupported(context.contentResolver)) { throw IllegalStateException("AutoOnFeature not supported for user: ${context.getUser()}") } + if (isFeatureEnabledForUser(context.contentResolver) && status == true) { + Log.i(TAG, "setUserEnabled: Nothing to do, feature is already enabled") + return + } if (!setFeatureEnabledForUserUnchecked(context, status)) { throw IllegalStateException("AutoOnFeature database failure for user: ${context.getUser()}") } -- GitLab From e77379cfe6553164e1852bcbeef4dae94dcd0537 Mon Sep 17 00:00:00 2001 From: William Escande Date: Tue, 11 Jun 2024 16:39:10 -0700 Subject: [PATCH 0009/1446] CppLint: allow for 100 line length 100 is the default line length in AOSP Bug: 311772251 Test: None Flag: Exempt, not applicable for style Change-Id: I68af1eb753efb0d1abc7f618a07e549ee6011871 --- CPPLINT.cfg | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 CPPLINT.cfg diff --git a/CPPLINT.cfg b/CPPLINT.cfg new file mode 100644 index 00000000000..fa007befbe8 --- /dev/null +++ b/CPPLINT.cfg @@ -0,0 +1,2 @@ +set noparent +linelength=100 -- GitLab From f6c19d19f032756e9907563f0a1c730271e742a7 Mon Sep 17 00:00:00 2001 From: Bao Do Date: Tue, 11 Jun 2024 14:59:13 +0800 Subject: [PATCH 0010/1446] Add flag a2dp_check_lea_iso_channel Bug: 346475618 Bug: 341219050 Bug: 315241296 Flag: com.android.bluetooth.flags.a2dp_check_lea_iso_channel Test: mmm packages/modules/Bluetooth Change-Id: I77e9426f66ebbe3b2f457dff20a76d52c070ef21 --- flags/a2dp.aconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/flags/a2dp.aconfig b/flags/a2dp.aconfig index 4df649b8030..ddb191b7d7b 100644 --- a/flags/a2dp.aconfig +++ b/flags/a2dp.aconfig @@ -75,3 +75,13 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "a2dp_check_lea_iso_channel" + namespace: "bluetooth" + description: "Prevent A2DP stream from starting when LEA ISO channels are in use" + bug: "346475618" + metadata { + purpose: PURPOSE_BUGFIX + } +} -- GitLab From 7a64e3a9be862fee7a573f45c9ba84d5d61dae27 Mon Sep 17 00:00:00 2001 From: Bao Do Date: Tue, 11 Jun 2024 15:05:12 +0800 Subject: [PATCH 0011/1446] Add checking for active ISO channels before starting A2DP stream. This will help prevent race conditions when changing from LEA active device to A2DP for music streaming cases. Bug: 346475618 Bug: 341219050 Test: mmm packages/modules/Bluetooth/ Change-Id: Ib6e25a600e4766f1aab1088e72477069411dd0dc --- system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc | 10 ++++++++++ system/stack/btm/btm_iso.cc | 4 ++++ system/stack/btm/btm_iso_impl.h | 6 ++++++ system/stack/include/btm_iso_api.h | 5 +++++ system/test/mock/mock_stack_btm_iso.cc | 4 ++++ system/test/mock/mock_stack_btm_iso.h | 1 + 6 files changed, 30 insertions(+) diff --git a/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc b/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc index a8fc262dad9..d49c3672d70 100644 --- a/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc +++ b/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc @@ -18,6 +18,7 @@ #include "a2dp_encoding_aidl.h" #include +#include #include @@ -26,6 +27,7 @@ #include "audio_aidl_interfaces.h" #include "bta/av/bta_av_int.h" #include "btif/include/btif_common.h" +#include "btm_iso_api.h" #include "codec_status_aidl.h" #include "transport_instance.h" @@ -97,6 +99,14 @@ BluetoothAudioCtrlAck A2dpTransport::StartRequest(bool is_low_latency) { return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_INCALL_FAILURE); } + if (com::android::bluetooth::flags::a2dp_check_lea_iso_channel()) { + // Don't send START request to stack while LEA sessions are in use + if (hci::IsoManager::GetInstance()->GetNumberOfActiveIso() > 0) { + log::error("LEA currently has active ISO channels"); + return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE); + } + } + if (btif_av_stream_started_ready(A2dpType::kSource)) { // Already started, ACK back immediately. return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS); diff --git a/system/stack/btm/btm_iso.cc b/system/stack/btm/btm_iso.cc index 4f9a94449c2..e8eeec3a59b 100644 --- a/system/stack/btm/btm_iso.cc +++ b/system/stack/btm/btm_iso.cc @@ -90,6 +90,10 @@ void IsoManager::DisconnectCis(uint16_t cis_handle, uint8_t reason) { pimpl_->iso_impl_->disconnect_cis(cis_handle, reason); } +int IsoManager::GetNumberOfActiveIso() { + return pimpl_->iso_impl_->get_number_of_active_iso(); +} + void IsoManager::SetupIsoDataPath( uint16_t iso_handle, struct iso_manager::iso_data_path_params path_params) { pimpl_->iso_impl_->setup_iso_data_path(iso_handle, std::move(path_params)); diff --git a/system/stack/btm/btm_iso_impl.h b/system/stack/btm/btm_iso_impl.h index 276f1985a7c..0b124e9e3ad 100644 --- a/system/stack/btm/btm_iso_impl.h +++ b/system/stack/btm/btm_iso_impl.h @@ -342,6 +342,12 @@ struct iso_impl { hci_reason_code_text((tHCI_REASON)(reason)).c_str())); } + int get_number_of_active_iso() { + int num_iso = conn_hdl_to_cis_map_.size() + conn_hdl_to_bis_map_.size(); + log::info("Current number of active_iso is {}", num_iso); + return num_iso; + } + void on_setup_iso_data_path(uint8_t* stream, uint16_t /* len */) { uint8_t status; uint16_t conn_handle; diff --git a/system/stack/include/btm_iso_api.h b/system/stack/include/btm_iso_api.h index eb1bf376181..7e968e9d31d 100644 --- a/system/stack/include/btm_iso_api.h +++ b/system/stack/include/btm_iso_api.h @@ -226,6 +226,11 @@ class IsoManager { virtual void HandleHciEvent(uint8_t sub_code, uint8_t* params, uint16_t length); + /** + * Return the current number of ISO channels + */ + virtual int GetNumberOfActiveIso(); + /** * Starts the IsoManager module */ diff --git a/system/test/mock/mock_stack_btm_iso.cc b/system/test/mock/mock_stack_btm_iso.cc index 436a31c8e5e..06d1a4096ef 100644 --- a/system/test/mock/mock_stack_btm_iso.cc +++ b/system/test/mock/mock_stack_btm_iso.cc @@ -157,6 +157,10 @@ void IsoManager::Stop() { mock_pimpl_ = nullptr; } +int IsoManager::GetNumberOfActiveIso() { + return pimpl_->GetNumberOfActiveIso(); +} + void IsoManager::Dump(int /* fd */) {} IsoManager::~IsoManager() = default; diff --git a/system/test/mock/mock_stack_btm_iso.h b/system/test/mock/mock_stack_btm_iso.h index 9948f4cdf85..4d7a49634e5 100644 --- a/system/test/mock/mock_stack_btm_iso.h +++ b/system/test/mock/mock_stack_btm_iso.h @@ -50,6 +50,7 @@ struct MockIsoManager { (void), EstablishCis, (struct bluetooth::hci::iso_manager::cis_establish_params conn_params)); MOCK_METHOD((void), DisconnectCis, (uint16_t cis_handle, uint8_t reason)); + MOCK_METHOD((int), GetNumberOfActiveIso, ()); MOCK_METHOD( (void), SetupIsoDataPath, (uint16_t iso_handle, -- GitLab From 3996a0cfc2ab32b4923824f842138ac630c65a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20Ko=C5=82odziejczyk?= Date: Mon, 10 Jun 2024 07:46:33 +0000 Subject: [PATCH 0012/1446] le_audio: Allow broadcast handover fallback device clear With this change there is possibile clearance of fallback group id in case if active LE Audio unicast device would change to null. Tag: #Bug Bug: 338341279 Test: atest LeAudioServiceTest Flag: Exempt, simple fix Change-Id: I07a645493b7f05ae8811650eb205683bb91408e4 --- .../bluetooth/le_audio/LeAudioService.java | 19 ++++++++++++++++--- .../le_audio/LeAudioServiceTest.java | 6 ++++++ 2 files changed, 22 insertions(+), 3 deletions(-) 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 8a6244b998d..13f6f061dca 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java @@ -2124,17 +2124,30 @@ public class LeAudioService extends ProfileService { + ", mExposedActiveDevice: " + mExposedActiveDevice); + LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(currentlyActiveGroupId); if (isBroadcastActive() && currentlyActiveGroupId == LE_AUDIO_GROUP_ID_INVALID - && mUnicastGroupIdDeactivatedForBroadcastTransition != LE_AUDIO_GROUP_ID_INVALID - && groupId != LE_AUDIO_GROUP_ID_INVALID) { + && mUnicastGroupIdDeactivatedForBroadcastTransition != LE_AUDIO_GROUP_ID_INVALID) { // If broadcast is ongoing and need to update unicast fallback active group // we need to update the cached group id and skip changing the active device updateFallbackUnicastGroupIdForBroadcast(groupId); + + /* In case of removing fallback unicast group, monitoring input device should be + * removed from active devices. + */ + if (groupDescriptor != null && groupId == LE_AUDIO_GROUP_ID_INVALID) { + updateActiveDevices( + groupId, + groupDescriptor.mDirection, + AUDIO_DIRECTION_NONE, + false, + groupDescriptor.mHasFallbackDeviceWhenGettingInactive, + false); + } + return true; } - LeAudioGroupDescriptor groupDescriptor = getGroupDescriptor(currentlyActiveGroupId); if (groupDescriptor != null && groupId == currentlyActiveGroupId) { /* Make sure active group is already exposed to audio framework. * If not, lets wait for it and don't sent additional intent. diff --git a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java index 31fc520627b..84f5c7109cf 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java @@ -1623,6 +1623,12 @@ public class LeAudioServiceTest { // Verify only update the fallback group and not proceed to change active assertThat(mService.setActiveDevice(mSingleDevice)).isTrue(); assertThat(mService.mUnicastGroupIdDeactivatedForBroadcastTransition).isEqualTo(groupId); + + // Verify only update the fallback group to INVALID and not proceed to change active + assertThat(mService.setActiveDevice(null)).isTrue(); + assertThat(mService.mUnicastGroupIdDeactivatedForBroadcastTransition) + .isEqualTo(BluetoothLeAudio.GROUP_ID_INVALID); + verify(mNativeInterface, times(0)).groupSetActive(anyInt()); } -- GitLab From 65c08f2e526dea93775ed30b04f87c4e4045c645 Mon Sep 17 00:00:00 2001 From: Ruina Liu Date: Fri, 22 Mar 2024 06:36:57 +0000 Subject: [PATCH 0013/1446] HOGP connection with some HOGP devices were slowed down Updating connection parameter with non-zero latency before finishing HOGP connection causes some HOGP devices reponse slowly during profile connection. To avoid slowing down the connection, use interop list to set zero latency for those devices. They can request proper latency later based on its power state. Bug: 346692549 Test: m com.android.btservices Test pairing and reconnecting HOGP devices(Mad mouse) and confirm the connection won't be slow down. Change-Id: Ida03591bc4fa5137bd4b6960b4a92cf4f8ea3b15 --- system/bta/hh/bta_hh_le.cc | 5 +++++ system/conf/interop_database.conf | 6 ++++++ system/device/include/interop.h | 5 +++++ system/device/src/interop.cc | 1 + 4 files changed, 17 insertions(+) diff --git a/system/bta/hh/bta_hh_le.cc b/system/bta/hh/bta_hh_le.cc index 57253ea6030..b4b2b1dbf6e 100644 --- a/system/bta/hh/bta_hh_le.cc +++ b/system/bta/hh/bta_hh_le.cc @@ -1403,6 +1403,11 @@ static void read_pref_conn_params_cb(uint16_t conn_id, tGATT_STATUS status, if (timeout < 300) timeout = 300; } + if (interop_match_addr(INTEROP_HID_PREF_CONN_ZERO_LATENCY, + (RawAddress*)&p_dev_cb->link_spec.addrt.bda)) { + latency = 0; + } + BTM_BleSetPrefConnParams(p_dev_cb->link_spec.addrt.bda, min_interval, max_interval, latency, timeout); L2CA_UpdateBleConnParams(p_dev_cb->link_spec.addrt.bda, min_interval, diff --git a/system/conf/interop_database.conf b/system/conf/interop_database.conf index ffca2ceeecd..bb6dde0cdb3 100644 --- a/system/conf/interop_database.conf +++ b/system/conf/interop_database.conf @@ -872,3 +872,9 @@ EPG = Name_Based CANZ = Name_Based BSK30 = Name_Based BSK10 = Name_Based + +# Some devices response slowly after setting non zero latency. +# To avoid slowing down profile connection set latency to 0. +# Peer can request proper latency based on its power state later. +[INTEROP_HID_PREF_CONN_ZERO_LATENCY] +00:15:9E = Address_Based diff --git a/system/device/include/interop.h b/system/device/include/interop.h index 7003a58ada1..9554ac3fbb0 100644 --- a/system/device/include/interop.h +++ b/system/device/include/interop.h @@ -353,6 +353,11 @@ typedef enum { // Som A2DP sink devices don't respond SDP request during A2DP reconnection INTEROP_A2DP_SKIP_SDP_DURING_RECONNECTION, + // Some devices response slowly after setting non zero latency. + // To avoid slowing down profile connection set latency to 0. + // Peer can request proper latency based on its power state later. + INTEROP_HID_PREF_CONN_ZERO_LATENCY, + END_OF_INTEROP_LIST } interop_feature_t; diff --git a/system/device/src/interop.cc b/system/device/src/interop.cc index 47e4d8fcc22..4bddcd43d66 100644 --- a/system/device/src/interop.cc +++ b/system/device/src/interop.cc @@ -405,6 +405,7 @@ static const char* interop_feature_string_(const interop_feature_t feature) { CASE_RETURN_STR(INTEROP_DELAY_AUTH); CASE_RETURN_STR(INTEROP_MULTIPLE_HOGP_SERVICE_CHOOSE_THIRD); CASE_RETURN_STR(INTEROP_A2DP_SKIP_SDP_DURING_RECONNECTION); + CASE_RETURN_STR(INTEROP_HID_PREF_CONN_ZERO_LATENCY); } return UNKNOWN_INTEROP_FEATURE; } -- GitLab From 2827a3f9cca131a7fa0af3bb8f133e0ff6fe24ef Mon Sep 17 00:00:00 2001 From: Pomai Ahlo Date: Wed, 12 Jun 2024 23:24:42 +0000 Subject: [PATCH 0014/1446] Revert "RfcommTest: Disable HFP connections" This reverts commit 08378c42e4e7ba6fecaf22d08591b04dd7b3bc34. Reason for revert: b/344067713 Change-Id: Ie7a2445215f70a04cadbd68ae8e011c5e85622de --- .../src/android/bluetooth/RfcommTest.kt | 41 +------------------ 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/framework/tests/bumble/src/android/bluetooth/RfcommTest.kt b/framework/tests/bumble/src/android/bluetooth/RfcommTest.kt index a4d7be81790..94fc4f2c0b9 100644 --- a/framework/tests/bumble/src/android/bluetooth/RfcommTest.kt +++ b/framework/tests/bumble/src/android/bluetooth/RfcommTest.kt @@ -31,16 +31,11 @@ import io.grpc.stub.StreamObserver import java.time.Duration import java.util.UUID import java.util.concurrent.TimeUnit -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.channels.trySendBlocking +import kotlinx.coroutines.* +import kotlinx.coroutines.channels.* import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.consumeAsFlow import kotlinx.coroutines.flow.first -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.withTimeout import org.junit.After import org.junit.Before import org.junit.Rule @@ -320,10 +315,6 @@ class RfcommTest { @OptIn(ExperimentalCoroutinesApi::class) private suspend fun bondDevice(remoteDevice: BluetoothDevice) { - // TODO: b/345842833 - // HFP will try to connect, and bumble doesn't support HFP yet - disableHfp() - if (mAdapter.bondedDevices.contains(remoteDevice)) { Log.d(TAG, "bondDevice(): The device is already bonded") return @@ -367,34 +358,6 @@ class RfcommTest { } } - private fun disableHfp() = - runBlocking { - val proxy = headsetFlow().first() - proxy.setConnectionPolicy(mBumbleDevice, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) - } - - private suspend fun headsetFlow(): Flow { - return callbackFlow { - val listener = - object : BluetoothProfile.ServiceListener { - lateinit var mBluetoothHeadset: BluetoothHeadset - - override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) { - mBluetoothHeadset = proxy as BluetoothHeadset - trySend(mBluetoothHeadset) - } - - override fun onServiceDisconnected(profile: Int) {} - } - - mAdapter.getProfileProxy(mContext, listener, BluetoothProfile.HEADSET) - - awaitClose { - mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, listener.mBluetoothHeadset) - } - } - } - companion object { private val TAG = RfcommTest::class.java.getSimpleName() private val GRPC_TIMEOUT = Duration.ofSeconds(10) -- GitLab From 223baad506c4c88fef119a1da47db246befb8019 Mon Sep 17 00:00:00 2001 From: Kyunglyul Hyun Date: Thu, 23 May 2024 07:28:36 +0000 Subject: [PATCH 0015/1446] Use ConcurrentHashMap for mPanDevices It will prevent CMEs. Bug: 318100317 Flag: EXEMPT, do not include logical change Test: atest PanServiceTest Change-Id: I7fd4432c2239d0b31a2680d83b09a8bd4fe15072 --- android/app/src/com/android/bluetooth/pan/PanService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/android/app/src/com/android/bluetooth/pan/PanService.java b/android/app/src/com/android/bluetooth/pan/PanService.java index 418df87936e..42df4219d40 100644 --- a/android/app/src/com/android/bluetooth/pan/PanService.java +++ b/android/app/src/com/android/bluetooth/pan/PanService.java @@ -57,6 +57,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; /** Provides Bluetooth Pan Device profile, as a service in the Bluetooth application. */ public class PanService extends ProfileService { @@ -65,7 +66,8 @@ public class PanService extends ProfileService { private static final int BLUETOOTH_MAX_PAN_CONNECTIONS = 5; - @VisibleForTesting HashMap mPanDevices; + @VisibleForTesting ConcurrentHashMap mPanDevices; + private int mMaxPanDevices; private String mPanIfName; @VisibleForTesting boolean mIsTethering = false; @@ -151,7 +153,7 @@ public class PanService extends ProfileService { "PanNativeInterface cannot be null when PanService starts"); mBluetoothTetheringCallbacks = new HashMap<>(); - mPanDevices = new HashMap(); + mPanDevices = new ConcurrentHashMap(); try { mMaxPanDevices = getResources() @@ -693,7 +695,6 @@ public class PanService extends ProfileService { } } else if (mStarted) { // PANU Role = reverse Tether - Log.d( TAG, "handlePanDeviceStateChange LOCAL_PANU_ROLE:REMOTE_NAP_ROLE state = " @@ -713,7 +714,6 @@ public class PanService extends ProfileService { mPanDevices.remove(device); } } - if (state == BluetoothProfile.STATE_CONNECTED) { MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.PAN); } -- GitLab From d454b17727f977f96691556e445dbf40f9754919 Mon Sep 17 00:00:00 2001 From: Katherine Lai Date: Mon, 10 Jun 2024 21:44:22 +0000 Subject: [PATCH 0016/1446] floss: Add IsLEAudioStable API Add new API that returns true for a remote device if its model is in the allowlist. The allowlist is stored as sysprop persist.bluetooth.leaudio.allow_list. Add handling for getting this sysprop in Rust. Also add RemoteModelName property in btif to get the remote device's model name. Bug: 341977695 Tag: #floss Test: btclient - device info Test: mmm packages/modules/Bluetooth Flag: EXEMPT, floss change for ChromeOS only Change-Id: Iafe55d86a0cd67ad20214b9c534fc4bd2420d0e7 --- .../rust/linux/client/src/command_handler.rs | 4 ++ system/gd/rust/linux/client/src/dbus_iface.rs | 5 ++ .../rust/linux/service/src/iface_bluetooth.rs | 5 ++ system/gd/rust/linux/stack/src/bluetooth.rs | 19 ++++++- system/gd/rust/topshim/src/btif.rs | 11 ++++- system/gd/rust/topshim/src/sysprop.rs | 49 ++++++++++++++++++- system/gd/sysprops/sysprops_module.cc | 1 + 7 files changed, 91 insertions(+), 3 deletions(-) diff --git a/system/gd/rust/linux/client/src/command_handler.rs b/system/gd/rust/linux/client/src/command_handler.rs index e586eb51935..25ad024d8a5 100644 --- a/system/gd/rust/linux/client/src/command_handler.rs +++ b/system/gd/rust/linux/client/src/command_handler.rs @@ -889,6 +889,7 @@ impl CommandHandler { uuids, wake_allowed, dual_mode_audio, + le_audio_stable, ) = { let ctx = self.lock_context(); let adapter = ctx.adapter_dbus.as_ref().unwrap(); @@ -908,6 +909,7 @@ impl CommandHandler { let uuids = adapter.get_remote_uuids(device.clone()); let wake_allowed = adapter.get_remote_wake_allowed(device.clone()); let dual_mode_audio = adapter.is_dual_mode_audio_sink_device(device.clone()); + let le_audio_stable = adapter.is_le_audio_stable(device.clone()); ( name, @@ -921,6 +923,7 @@ impl CommandHandler { uuids, wake_allowed, dual_mode_audio, + le_audio_stable, ) }; @@ -935,6 +938,7 @@ impl CommandHandler { print_info!("Bond State: {:?}", bonded); print_info!("Connection State: {}", connection_state); print_info!("Dual Mode Audio Device: {}", dual_mode_audio); + print_info!("Is LE Audio Stable: {}", le_audio_stable); print_info!( "Uuids: {}", DisplayList( diff --git a/system/gd/rust/linux/client/src/dbus_iface.rs b/system/gd/rust/linux/client/src/dbus_iface.rs index 6a2fe45b119..e3f070e70ac 100644 --- a/system/gd/rust/linux/client/src/dbus_iface.rs +++ b/system/gd/rust/linux/client/src/dbus_iface.rs @@ -1036,6 +1036,11 @@ impl IBluetooth for BluetoothDBus { dbus_generated!() } + #[dbus_method("IsLEAudioStable")] + fn is_le_audio_stable(&self, device: BluetoothDevice) -> bool { + dbus_generated!() + } + #[dbus_method("GetDumpsys")] fn get_dumpsys(&self) -> String { dbus_generated!() diff --git a/system/gd/rust/linux/service/src/iface_bluetooth.rs b/system/gd/rust/linux/service/src/iface_bluetooth.rs index 063b3331344..3a1fc6530ef 100644 --- a/system/gd/rust/linux/service/src/iface_bluetooth.rs +++ b/system/gd/rust/linux/service/src/iface_bluetooth.rs @@ -771,6 +771,11 @@ impl IBluetooth for IBluetoothDBus { dbus_generated!() } + #[dbus_method("IsLEAudioStable", DBusLog::Disable)] + fn is_le_audio_stable(&self, device: BluetoothDevice) -> bool { + dbus_generated!() + } + #[dbus_method("GetDumpsys", DBusLog::Disable)] fn get_dumpsys(&self) -> String { dbus_generated!() diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs index 7898e8b57bc..69388bcd8d2 100644 --- a/system/gd/rust/linux/stack/src/bluetooth.rs +++ b/system/gd/rust/linux/stack/src/bluetooth.rs @@ -17,7 +17,7 @@ use bt_topshim::{ }, profiles::sdp::{BtSdpRecord, Sdp, SdpCallbacks, SdpCallbacksDispatcher}, profiles::ProfileConnectionState, - topstack, + sysprop, topstack, }; use bt_utils::array_utils; @@ -265,6 +265,9 @@ pub trait IBluetooth { /// LE Audio sink roles). fn is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool; + /// Returns whether the remote device is LE audio stable. + fn is_le_audio_stable(&self, device: BluetoothDevice) -> bool; + /// Gets diagnostic output. fn get_dumpsys(&self) -> String; } @@ -3004,6 +3007,20 @@ impl IBluetooth for Bluetooth { }) } + fn is_le_audio_stable(&self, device: BluetoothDevice) -> bool { + let model_name = + match self.get_remote_device_property(&device, &BtPropertyType::RemoteModelName) { + Some(BluetoothProperty::RemoteModelName(name)) => name, + _ => { + return false; + } + }; + + sysprop::get_string(sysprop::PropertyString::LeAudioAllowList) + .split(",") + .any(|model| model == model_name) + } + fn get_dumpsys(&self) -> String { NamedTempFile::new() .and_then(|file| { diff --git a/system/gd/rust/topshim/src/btif.rs b/system/gd/rust/topshim/src/btif.rs index 0ce1be07d57..4b9e1b91277 100644 --- a/system/gd/rust/topshim/src/btif.rs +++ b/system/gd/rust/topshim/src/btif.rs @@ -167,7 +167,7 @@ pub enum BtPropertyType { // Unimplemented: // BT_PROPERTY_REMOTE_ASHA_CAPABILITY, // BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID, - // BT_PROPERTY_REMOTE_MODEL_NUM, + RemoteModelName = 0x17, RemoteAddrType = 0x18, Unknown = 0xFE, @@ -583,6 +583,7 @@ pub enum BluetoothProperty { RemoteIsCoordinatedSetMember(bool), Appearance(u16), VendorProductInfo(BtVendorProductInfo), + RemoteModelName(String), RemoteAddrType(BtAddrType), RemoteDeviceTimestamp(), @@ -627,6 +628,7 @@ impl BluetoothProperty { BluetoothProperty::Appearance(_) => BtPropertyType::Appearance, BluetoothProperty::VendorProductInfo(_) => BtPropertyType::VendorProductInfo, BluetoothProperty::RemoteDeviceTimestamp() => BtPropertyType::RemoteDeviceTimestamp, + BluetoothProperty::RemoteModelName(_) => BtPropertyType::RemoteModelName, BluetoothProperty::RemoteAddrType(_) => BtPropertyType::RemoteAddrType, BluetoothProperty::Unknown() => BtPropertyType::Unknown, } @@ -658,6 +660,7 @@ impl BluetoothProperty { BluetoothProperty::RemoteIsCoordinatedSetMember(_) => mem::size_of::(), BluetoothProperty::Appearance(_) => mem::size_of::(), BluetoothProperty::VendorProductInfo(_) => mem::size_of::(), + BluetoothProperty::RemoteModelName(name) => name.len(), BluetoothProperty::RemoteAddrType(_) => mem::size_of::(), // TODO(abps) - Figure out sizes for these @@ -767,6 +770,9 @@ impl BluetoothProperty { }; data.copy_from_slice(&slice); } + BluetoothProperty::RemoteModelName(name) => { + data.copy_from_slice(name.as_bytes()); + } BluetoothProperty::RemoteAddrType(addr_type) => { data.copy_from_slice( &BtAddrType::to_u32(addr_type).unwrap_or_default().to_ne_bytes(), @@ -848,6 +854,9 @@ impl From for BluetoothProperty { let v = unsafe { (prop.val as *const BtVendorProductInfo).read_unaligned() }; BluetoothProperty::VendorProductInfo(BtVendorProductInfo::from(v)) } + BtPropertyType::RemoteModelName => { + BluetoothProperty::RemoteModelName(ascii_to_string(slice, len)) + } BtPropertyType::RemoteAddrType => BluetoothProperty::RemoteAddrType( BtAddrType::from_u32(u32_from_bytes(slice)).unwrap_or(BtAddrType::Unknown), ), diff --git a/system/gd/rust/topshim/src/sysprop.rs b/system/gd/rust/topshim/src/sysprop.rs index 6dd00845678..00201347050 100644 --- a/system/gd/rust/topshim/src/sysprop.rs +++ b/system/gd/rust/topshim/src/sysprop.rs @@ -3,7 +3,9 @@ use std::ffi::CString; use crate::bindings::root as bindings; -use crate::utils::LTCheckedPtr; +use crate::utils::{LTCheckedPtr, LTCheckedPtrMut}; + +const PROPERTY_VALUE_MAX: usize = 92; /// List of properties accessible to Rust. Add new ones here as they become /// necessary. @@ -94,3 +96,48 @@ pub fn get_bool(prop: PropertyBool) -> bool { // SAFETY: Calling C++ function with compatible types (null terminated string and bool) is safe. unsafe { bindings::osi_property_get_bool(key_cptr.into(), default_value) } } + +/// List of string properties accessible to Rust. Add new ones here as they become +/// necessary. +pub enum PropertyString { + // bluetooth.le_audio + LeAudioAllowList, +} + +impl Into<(CString, CString)> for PropertyString { + /// Convert the property into the property key name and a default value. + fn into(self) -> (CString, CString) { + let (key, default_value) = match self { + PropertyString::LeAudioAllowList => ("persist.bluetooth.leaudio.allow_list", ""), + }; + + ( + CString::new(key).expect("CString::new failed on sysprop key"), + CString::new(default_value).expect("CString::new failed on sysprop default_value"), + ) + } +} + +/// Get the string value for a system property. +pub fn get_string(prop: PropertyString) -> String { + let (key, default_value): (CString, CString) = prop.into(); + let key_cptr = LTCheckedPtr::from(&key); + let default_val_cptr = LTCheckedPtr::from(&default_value); + let mut dest = vec![0u8; PROPERTY_VALUE_MAX]; + let dest_cptr = LTCheckedPtrMut::from(&mut dest); + + // SAFETY: Calling C++ function with compatible types (null terminated strings) is safe. + let len = unsafe { + bindings::osi_property_get( + key_cptr.into(), + dest_cptr.cast_into::(), + default_val_cptr.into(), + ) + }; + if len <= 0 { + return "".to_string(); + } + + dest.resize(len as usize, b'\0'); + String::from_utf8(dest).expect("Found invalid UTF-8") +} diff --git a/system/gd/sysprops/sysprops_module.cc b/system/gd/sysprops/sysprops_module.cc index 64b9e19fe07..e0a2923a287 100644 --- a/system/gd/sysprops/sysprops_module.cc +++ b/system/gd/sysprops/sysprops_module.cc @@ -122,6 +122,7 @@ void SyspropsModule::parse_config(std::string file_path) { // LE Audio "bluetooth.le_audio.enable_le_audio_only", "bluetooth.leaudio.dual_bidirection_swb.supported", + "persist.bluetooth.leaudio.allow_list", // SCO "bluetooth.sco.disable_enhanced_connection", "bluetooth.sco.swb_supported", -- GitLab From 5f7a6fdc83008e7a12a7fe45a760f4370ada1720 Mon Sep 17 00:00:00 2001 From: Etienne Ruffieux Date: Wed, 17 Apr 2024 09:32:32 +0000 Subject: [PATCH 0017/1446] AVRCP Browsing refactor Small refactor of AVRCP target browsing. Current implementation doesn't follow the BT spec and is load heavy on BT startup. Features: - Change the MediaBrowser connection to when a BT event is requesting it. Connection is kept alive for 5 seconds in order to prevent multiple connection/disconnection while browsing. - "Bluetooth player" has been removed, the list of browsable players now contains all browsable players. - Browsable player validation is now done by fetching packages that both support browsing and audio playing. - Package add/removal is now supported for browsed players and the update is broadcasted. - Overall stability of AVRCP browsing should be increased. - Non-browsable players are also sent in getFolderItems for MediaPlayerList. This should enable to select a non- browsable player from the remote to play. Bug: 319275147 Bug: 326492797 Bug: 332465445 Bug: 326132268 Bug: 304805334 Flag: com.android.bluetooth.flags.browsing_refactor Test: atest BluetoothInstrumentationTests Change-Id: I97eda027df1f6bf727832051cc2d55070378851f --- .../audio_util/MediaBrowserWrapper.java | 389 ++++++++++++ .../bluetooth/audio_util/MediaPlayerList.java | 594 +++++++++++------- 2 files changed, 771 insertions(+), 212 deletions(-) create mode 100644 android/app/src/com/android/bluetooth/audio_util/MediaBrowserWrapper.java diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaBrowserWrapper.java b/android/app/src/com/android/bluetooth/audio_util/MediaBrowserWrapper.java new file mode 100644 index 00000000000..c330cbaf37b --- /dev/null +++ b/android/app/src/com/android/bluetooth/audio_util/MediaBrowserWrapper.java @@ -0,0 +1,389 @@ +/* + * 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. + */ + +package com.android.bluetooth.audio_util; + +import android.content.ComponentName; +import android.content.Context; +import android.media.browse.MediaBrowser.MediaItem; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; + +import com.android.bluetooth.R; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +/** + * Handles API calls to a MediaBrowser. + * + *

{@link MediaBrowser} APIs work with callbacks only and need a connection beforehand. + * + *

This class handles the connection then will call the appropriate API and trigger the given + * callback when it gets the answer from MediaBrowser. + */ +class MediaBrowserWrapper { + + private static final String TAG = MediaBrowserWrapper.class.getSimpleName(); + + /** + * Some devices will continuously request each item in a folder one at a time. + * + *

This timeout is here to remove the connection between this class and the {@link + * MediaBrowser} after a certain time without requests from the remote device to browse the + * player. If the next request happens soon after, the bound will still exist. + * + *

Note: Previous implementation was keeping a local list of fetched items, this worked at + * the cost of not having the items actualized if fetching again the same folder. + */ + private static final Duration BROWSER_DISCONNECT_TIMEOUT = Duration.ofSeconds(5); + + private enum ConnectionState { + DISCONNECTED, + CONNECTING, + CONNECTED, + } + + public interface RequestCallback { + void run(); + } + + public interface GetPlayerRootCallback { + void run(String rootId); + } + + public interface GetFolderItemsCallback { + void run(String parentId, List items); + } + + private final MediaBrowser mWrappedBrowser; + private final Context mContext; + private final Looper mLooper; + private final String mPackageName; + private final Handler mRunHandler; + + private ConnectionState mBrowserConnectionState = ConnectionState.DISCONNECTED; + + private final ArrayList mRequestsList = new ArrayList<>(); + + // GetFolderItems also works with a callback, so we need to store all requests made before we + // got the results and prevent new subscriptions. + private final HashMap> mSubscribedIds = + new HashMap<>(); + + private final Runnable mDisconnectRunnable = () -> _disconnect(); + + public MediaBrowserWrapper( + Context context, Looper looper, String packageName, String className) { + mContext = context; + mPackageName = packageName; + mLooper = looper; + mRunHandler = new Handler(mLooper); + mWrappedBrowser = + MediaBrowserFactory.make( + context, + new ComponentName(packageName, className), + new MediaConnectionCallback(), + null); + } + + /** Returns the package name of the {@link MediaBrowser}. */ + public final String getPackageName() { + Log.v(TAG, "getPackageName: " + mPackageName); + return mPackageName; + } + + /** Retrieves the root path of the {@link MediaBrowser}. */ + public void getRootId(GetPlayerRootCallback callback) { + Log.v(TAG, "getRootId: " + mPackageName); + browseRequest( + () -> { + if (mBrowserConnectionState != ConnectionState.CONNECTED) { + Log.e(TAG, "getRootId: cb triggered but MediaBrowser is not connected."); + callback.run(""); + return; + } + String rootId = mWrappedBrowser.getRoot(); + Log.v(TAG, "getRootId for " + mPackageName + ": " + rootId); + callback.run(rootId); + setDisconnectDelay(); + }); + } + + /** Plays the specified {@code mediaId}. */ + public void playItem(String mediaId) { + Log.v(TAG, "playItem for " + mPackageName + ": " + mediaId); + browseRequest( + () -> { + if (mBrowserConnectionState != ConnectionState.CONNECTED) { + Log.e(TAG, "playItem: cb triggered but MediaBrowser is not connected."); + return; + } + setDisconnectDelay(); + // Retrieve the MediaController linked with this MediaBrowser. + // Note that the MediaBrowser should be connected for this. + MediaController controller = + MediaControllerFactory.make( + mContext, mWrappedBrowser.getSessionToken()); + // Retrieve TransportControls from this MediaController and play mediaId + MediaController.TransportControls ctrl = controller.getTransportControls(); + Log.v(TAG, "playItem for " + mPackageName + ": " + mediaId + " playing."); + ctrl.playFromMediaId(mediaId, null); + }); + } + + /** + * Retrieves the content of a specific {@link MediaBrowser} path. + * + * @param mediaId the path to retrieve content of + * @param callback to be called when the content list is retrieved + */ + public void getFolderItems(String mediaId, GetFolderItemsCallback callback) { + Log.v(TAG, "getFolderItems for " + mPackageName + " and " + mediaId); + browseRequest( + () -> { + if (mBrowserConnectionState != ConnectionState.CONNECTED) { + Log.e( + TAG, + "getFolderItems: cb triggered but MediaBrowser is not connected."); + callback.run(mediaId, Collections.emptyList()); + return; + } + setDisconnectDelay(); + if (mSubscribedIds.containsKey(mediaId)) { + Log.v( + TAG, + "getFolderItems for " + + mPackageName + + " and " + + mediaId + + ": adding callback, already subscribed."); + ArrayList newList = + (ArrayList) mSubscribedIds.get(mediaId); + newList.add(callback); + mSubscribedIds.put(mediaId, newList); + return; + } + Log.v( + TAG, + "getFolderItems for " + + mPackageName + + " and " + + mediaId + + ": adding callback and subscribing."); + mSubscribedIds.put(mediaId, new ArrayList<>(Arrays.asList(callback))); + mWrappedBrowser.subscribe( + mediaId, new BrowserSubscriptionCallback(mLooper, mediaId)); + }); + } + + /** + * Requests information from {@link MediaBrowser}. + * + *

If the {@link MediaBrowser} this instance wraps around is already connected, calls the + * callback directly. + * + *

If it is connecting, adds the callback to the {@code mRequestsList}, to be called once the + * connection is done. + * + *

If the connection isn't started, starts it and adds the callback to the {@code + * mRequestsList} + */ + private void browseRequest(RequestCallback callback) { + mRunHandler.post( + () -> { + switch (mBrowserConnectionState) { + case CONNECTED: + callback.run(); + break; + case DISCONNECTED: + connect(); + mRequestsList.add(callback); + break; + case CONNECTING: + mRequestsList.add(callback); + break; + } + }); + } + + /** Connects to the {@link MediaBrowser} this instance wraps around. */ + private void connect() { + if (mBrowserConnectionState != ConnectionState.DISCONNECTED) { + Log.e( + TAG, + "Trying to bind to a player that is not disconnected: " + + mBrowserConnectionState); + return; + } + mBrowserConnectionState = ConnectionState.CONNECTING; + Log.v(TAG, "connect: " + mPackageName + " connecting"); + mWrappedBrowser.connect(); + } + + /** Disconnects from the {@link MediaBrowser} */ + public void disconnect() { + mRunHandler.post(() -> _disconnect()); + } + + private void _disconnect() { + mRunHandler.removeCallbacks(mDisconnectRunnable); + if (mBrowserConnectionState == ConnectionState.DISCONNECTED) { + Log.e( + TAG, + "disconnect: Trying to disconnect a player that is not connected: " + + mBrowserConnectionState); + return; + } + mBrowserConnectionState = ConnectionState.DISCONNECTED; + Log.v(TAG, "disconnect: " + mPackageName + " disconnected"); + mWrappedBrowser.disconnect(); + } + + /** Sets the delay before the disconnection from the {@link MediaBrowser} happens. */ + private void setDisconnectDelay() { + mRunHandler.removeCallbacks(mDisconnectRunnable); + mRunHandler.postDelayed(mDisconnectRunnable, BROWSER_DISCONNECT_TIMEOUT.toMillis()); + } + + /** Callback for {@link MediaBrowser} connection. */ + private class MediaConnectionCallback extends MediaBrowser.ConnectionCallback { + @Override + public void onConnected() { + mRunHandler.post( + () -> { + mBrowserConnectionState = ConnectionState.CONNECTED; + Log.v(TAG, "MediaConnectionCallback: " + mPackageName + " onConnected"); + runCallbacks(); + }); + } + + @Override + public void onConnectionFailed() { + mRunHandler.post( + () -> { + Log.e( + TAG, + "MediaConnectionCallback: " + mPackageName + " onConnectionFailed"); + mBrowserConnectionState = ConnectionState.DISCONNECTED; + runCallbacks(); + }); + } + + @Override + public void onConnectionSuspended() { + mRunHandler.post( + () -> { + Log.e( + TAG, + "MediaConnectionCallback: " + + mPackageName + + " onConnectionSuspended"); + runCallbacks(); + mWrappedBrowser.disconnect(); + }); + } + + /** + * Executes all the callbacks stored during the connection process + * + *

This has to run on constructor's Looper. + */ + private void runCallbacks() { + for (RequestCallback callback : mRequestsList) { + callback.run(); + } + mRequestsList.clear(); + } + } + + private class BrowserSubscriptionCallback extends MediaBrowser.SubscriptionCallback { + + private final Runnable mTimeoutRunnable; + private boolean mCallbacksExecuted = false; + + public BrowserSubscriptionCallback(Looper looper, String mediaId) { + mTimeoutRunnable = + () -> { + executeCallbacks(mediaId, new ArrayList<>()); + }; + mRunHandler.postDelayed(mTimeoutRunnable, BROWSER_DISCONNECT_TIMEOUT.toMillis()); + } + + private void executeCallbacks(String parentId, ArrayList browsableContent) { + if (mCallbacksExecuted) { + return; + } + mCallbacksExecuted = true; + mRunHandler.removeCallbacks(mTimeoutRunnable); + for (GetFolderItemsCallback callback : mSubscribedIds.get(parentId)) { + Log.v( + TAG, + "getFolderItems for " + + mPackageName + + " and " + + parentId + + ": callback called with " + + browsableContent.size() + + " items."); + callback.run(parentId, browsableContent); + } + + mSubscribedIds.remove(parentId); + mWrappedBrowser.unsubscribe(parentId); + } + + @Override + public void onChildrenLoaded(String parentId, List children) { + + ArrayList browsableContent = new ArrayList<>(); + + for (MediaItem item : children) { + if (item.isBrowsable()) { + String title = item.getDescription().getTitle().toString(); + if (title.isEmpty()) { + title = mContext.getString(R.string.not_provided); + } + Folder f = new Folder(item.getMediaId(), false, title); + browsableContent.add(new ListItem(f)); + } else { + Metadata data = Util.toMetadata(mContext, item); + if (Util.isEmptyData(data)) { + continue; + } + browsableContent.add(new ListItem(data)); + } + } + + mRunHandler.post(() -> executeCallbacks(parentId, browsableContent)); + } + + @Override + public void onError(String parentId) { + mRunHandler.post(() -> executeCallbacks(parentId, new ArrayList<>())); + } + + @Override + public Handler getTimeoutHandler() { + return mRunHandler; + } + } +} diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java index 7b6b6bbd29d..69e25ff71ca 100644 --- a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java +++ b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java @@ -29,9 +29,11 @@ import android.media.AudioPlaybackConfiguration; import android.media.session.MediaSession; import android.media.session.MediaSessionManager; import android.media.session.PlaybackState; +import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.SystemProperties; +import android.provider.MediaStore; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; @@ -53,16 +55,7 @@ import java.util.regex.Pattern; /** * This class is directly responsible of maintaining the list of Browsable Players as well as the - * list of Addressable Players. This variation of the list doesn't actually list all the available - * players for a getAvailableMediaPlayers request. Instead it only reports one media player with - * ID=0 and all the other browsable players are folders in the root of that player. - * - *

Changing the directory to a browsable player will allow you to traverse that player as normal. - * By only having one root player, we never have to send Addressed Player Changed notifications, - * UIDs Changed notifications, or Available Players Changed notifications. - * - *

TODO (apanicke): Add non-browsable players as song items to the root folder. Selecting that - * player would effectively cause player switch by sending a play command to that player. + * list of Addressable Players. */ public class MediaPlayerList { private static final String TAG = MediaPlayerList.class.getSimpleName(); @@ -105,7 +98,10 @@ public class MediaPlayerList { Collections.synchronizedMap(new HashMap()); private Map mBrowsablePlayers = Collections.synchronizedMap(new HashMap()); + private Map mMediaBrowserWrappers = + Collections.synchronizedMap(new HashMap()); private int mActivePlayerId = NO_ACTIVE_PLAYER; + private int mBrowsingPlayerId = NO_ACTIVE_PLAYER; private MediaUpdateCallback mCallback; private boolean mAudioPlaybackIsActive = false; @@ -198,75 +194,100 @@ public class MediaPlayerList { } } - /** Initiates browsable players and calls {@link #constructCurrentPlayers}. */ + /** Initiates the media and browsable players list. */ public void init(MediaUpdateCallback callback) { Log.v(TAG, "Initializing MediaPlayerList"); mCallback = callback; if (!SystemProperties.getBoolean("bluetooth.avrcp.browsable_media_player.enabled", true)) { // Allow to disable BrowsablePlayerConnector with systemproperties. - // This is useful when for watches because: - // 1. It is not a regular use case - // 2. Registering to all players is a very loading task + // This is useful when for watches because it is not a regular use case Log.i(TAG, "init: without Browsable Player"); constructCurrentPlayers(); return; } - // Build the list of browsable players and afterwards, build the list of media players - Intent intent = new Intent(android.service.media.MediaBrowserService.SERVICE_INTERFACE); - if (Flags.keepStoppedMediaBrowserService()) { - // Don't query stopped apps, that would end up unstopping them - intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); - } - List playerList = - mContext.getApplicationContext() - .getPackageManager() - .queryIntentServices(intent, PackageManager.MATCH_ALL); - - mBrowsablePlayerConnector = - BrowsablePlayerConnector.connectToPlayers( - mContext, - mLooper, - playerList, - (List players) -> { - Log.i(TAG, "init: Browsable Player list size is " + players.size()); - - // Check to see if the list has been cleaned up before this completed - if (mMediaSessionManager == null) { - return; - } + initPlayersLists(); + } - for (BrowsedPlayerWrapper wrapper : players) { - // Generate new id and add the browsable player - if (!havePlayerId(wrapper.getPackageName())) { - mMediaPlayerIds.put( - wrapper.getPackageName(), getFreeMediaPlayerId()); + private void initPlayersLists() { + if (Flags.browsingRefactor()) { + // Instantiate the media players list + constructCurrentPlayers(); + // Instantiate the browsable players list + for (ResolveInfo info : getValidBrowsablePlayersPackages()) { + MediaBrowserWrapper wrapper = + new MediaBrowserWrapper( + mContext, + mLooper, + info.serviceInfo.packageName, + info.serviceInfo.name); + + if (!havePlayerId(wrapper.getPackageName())) { + mMediaPlayerIds.put(wrapper.getPackageName(), getFreeMediaPlayerId()); + } + mMediaBrowserWrappers.put(mMediaPlayerIds.get(wrapper.getPackageName()), wrapper); + } + } else { + // Build the list of browsable players and afterwards, build the list of media players + Intent intent = new Intent(android.service.media.MediaBrowserService.SERVICE_INTERFACE); + if (Flags.keepStoppedMediaBrowserService()) { + // Don't query stopped apps, that would end up unstopping them + intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); + } + List playerList = + mContext.getApplicationContext() + .getPackageManager() + .queryIntentServices(intent, PackageManager.MATCH_ALL); + + mBrowsablePlayerConnector = + BrowsablePlayerConnector.connectToPlayers( + mContext, + mLooper, + playerList, + (List players) -> { + Log.i(TAG, "init: Browsable Player list size is " + players.size()); + + // Check to see if the list has been cleaned up before this + // completed + if (mMediaSessionManager == null) { + return; } - d( - "Adding Browser Wrapper for " - + wrapper.getPackageName() - + " with id " - + mMediaPlayerIds.get(wrapper.getPackageName())); - - mBrowsablePlayers.put( - mMediaPlayerIds.get(wrapper.getPackageName()), wrapper); - - wrapper.getFolderItems( - wrapper.getRootId(), - (int status, String mediaId, List results) -> { - d( - "Got the contents for: " - + mediaId - + " : num results=" - + results.size()); - }); - } + for (BrowsedPlayerWrapper wrapper : players) { + // Generate new id and add the browsable player + if (!havePlayerId(wrapper.getPackageName())) { + mMediaPlayerIds.put( + wrapper.getPackageName(), getFreeMediaPlayerId()); + } + + d( + "Adding Browser Wrapper for " + + wrapper.getPackageName() + + " with id " + + mMediaPlayerIds.get( + wrapper.getPackageName())); + + mBrowsablePlayers.put( + mMediaPlayerIds.get(wrapper.getPackageName()), wrapper); + + wrapper.getFolderItems( + wrapper.getRootId(), + (int status, + String mediaId, + List results) -> { + d( + "Got the contents for: " + + mediaId + + " : num results=" + + results.size()); + }); + } - constructCurrentPlayers(); - }); + constructCurrentPlayers(); + }); + } } public void cleanup() { @@ -274,6 +295,7 @@ public class MediaPlayerList { mContext.unregisterReceiver(mPackageChangedBroadcastReceiver); mActivePlayerId = NO_ACTIVE_PLAYER; + mBrowsingPlayerId = NO_ACTIVE_PLAYER; mMediaSessionManager.removeOnActiveSessionsChangedListener(mActiveSessionsChangedListener); mMediaSessionManager.removeOnMediaKeyEventSessionChangedListener( @@ -292,19 +314,26 @@ public class MediaPlayerList { if (mBrowsablePlayerConnector != null) { mBrowsablePlayerConnector.cleanup(); } - for (BrowsedPlayerWrapper player : mBrowsablePlayers.values()) { - player.disconnect(); + if (Flags.browsingRefactor()) { + for (MediaBrowserWrapper browser : mMediaBrowserWrappers.values()) { + browser.disconnect(); + } + mMediaBrowserWrappers.clear(); + } else { + for (BrowsedPlayerWrapper player : mBrowsablePlayers.values()) { + player.disconnect(); + } + mBrowsablePlayers.clear(); } - mBrowsablePlayers.clear(); } - /** - * Current player ID is always Bluetooth player ID. - * - *

All browsable players are subdirectories of Bluetooth player. - */ + /** returns the current player ID. */ public int getCurrentPlayerId() { - return BLUETOOTH_PLAYER_ID; + if (Flags.browsingRefactor()) { + return mBrowsingPlayerId; + } else { + return BLUETOOTH_PLAYER_ID; + } } /** Get the next ID available in the IDs map. */ @@ -332,57 +361,89 @@ public class MediaPlayerList { mMediaSessionManager.dispatchMediaKeyEvent(event, false); } - /** - * This is used by setBrowsedPlayer as the browsed player is always the Bluetooth player. - * - *

If the requested player ID is not {@link #BLUETOOTH_PLAYER_ID}, success will be false. - * - *

The number of items will be the number of browsable players as they all are direct - * subdirectories of the Bluetooth player ID. - * - *

The root ID will always be an empty string to correspond to bluetooth player ID. - */ public void getPlayerRoot(int playerId, GetPlayerRootCallback cb) { - /** M: Fix PTS AVRCP/TG/MCN/CB/BI-02-C fail @{ */ - if (Utils.isPtsTestMode()) { - d("PTS test mode: getPlayerRoot"); - BrowsedPlayerWrapper wrapper = mBrowsablePlayers.get(BLUETOOTH_PLAYER_ID + 1); - String itemId = wrapper.getRootId(); - - wrapper.getFolderItems( - itemId, - (status, id, results) -> { - if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) { - cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", 0); - return; - } - cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", results.size()); - }); - return; + if (Flags.browsingRefactor()) { + mBrowsingPlayerId = playerId; + if (haveMediaBrowser(playerId)) { + MediaBrowserWrapper wrapper = mMediaBrowserWrappers.get(playerId); + wrapper.getRootId( + (rootId) -> { + wrapper.getFolderItems( + rootId, + (parentId, itemList) -> { + cb.run(playerId, true, rootId, itemList.size()); + }); + }); + sendFolderUpdate(false, true, false); + } + } else { + /** M: Fix PTS AVRCP/TG/MCN/CB/BI-02-C fail @{ */ + if (Utils.isPtsTestMode()) { + d("PTS test mode: getPlayerRoot"); + BrowsedPlayerWrapper wrapper = mBrowsablePlayers.get(BLUETOOTH_PLAYER_ID + 1); + String itemId = wrapper.getRootId(); + + wrapper.getFolderItems( + itemId, + (status, id, results) -> { + if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) { + cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", 0); + return; + } + cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", results.size()); + }); + return; + } + /** + * @} + */ + cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", mBrowsablePlayers.size()); } - /** - * @} - */ - cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", mBrowsablePlayers.size()); } - /** - * Returns a list containing only the Bluetooth player. - * - *

See class documentation. - */ + /** Returns a list valid browsable players. */ public List getMediaPlayerList() { - PlayerInfo info = new PlayerInfo(); - info.id = BLUETOOTH_PLAYER_ID; - info.name = BLUETOOTH_PLAYER_NAME; - info.browsable = true; - if (mBrowsablePlayers.size() == 0) { - // Set Bluetooth Player as non-browable if there is not browsable player exist. - info.browsable = false; - } List ret = new ArrayList(); - ret.add(info); - + if (Flags.browsingRefactor()) { + // Add actual browsable players + for (MediaBrowserWrapper browser : mMediaBrowserWrappers.values()) { + Log.i( + TAG, + "getMediaPlayerList: Added browsable player: " + browser.getPackageName()); + PlayerInfo info = new PlayerInfo(); + info.id = mMediaPlayerIds.get(browser.getPackageName()); + info.name = Util.getDisplayName(mContext, browser.getPackageName()); + info.browsable = true; + ret.add(info); + } + Log.i(TAG, "getMediaPlayerList: number of mediaplayers: " + mMediaPlayers.size()); + // Also list non-browsable players, they can be selected if controller supports it. + for (MediaPlayerWrapper mediaPlayer : mMediaPlayers.values()) { + // Skip player if already added as browsable + if (haveMediaBrowser(mMediaPlayerIds.get(mediaPlayer.getPackageName()))) { + continue; + } + Log.i( + TAG, + "getMediaPlayerList: Added non browsable player: " + + mediaPlayer.getPackageName()); + PlayerInfo info = new PlayerInfo(); + info.id = mMediaPlayerIds.get(mediaPlayer.getPackageName()); + info.name = Util.getDisplayName(mContext, mediaPlayer.getPackageName()); + info.browsable = false; + ret.add(info); + } + } else { + PlayerInfo info = new PlayerInfo(); + info.id = BLUETOOTH_PLAYER_ID; + info.name = BLUETOOTH_PLAYER_NAME; + info.browsable = true; + if (mBrowsablePlayers.size() == 0) { + // Set Bluetooth Player as non-browable if there is not browsable player exist. + info.browsable = false; + } + ret.add(info); + } return ret; } @@ -478,7 +539,7 @@ public class MediaPlayerList { * *

If the {@code nowPlaying} parameter is true, this will try to select the item from the * current active player's queue. Otherwise this means that the item is from a browsable player - * and this calls {@link BrowsedPlayerWrapper} to handle the change. + * and this calls {@link MediaBrowserWrapper} to handle the change. */ public void playItem(int playerId, boolean nowPlaying, String mediaId) { if (nowPlaying) { @@ -512,60 +573,78 @@ public class MediaPlayerList { } /** - * Retrieves the {@link BrowsedPlayerWrapper} corresponding to the {@code mediaId} and plays it. + * Retrieves the {@link MediaBrowserWrapper} corresponding to the {@code mediaId} and plays it. * *

See {@link #playItem}. */ private void playFolderItem(String mediaId) { - d("playFolderItem: mediaId=" + mediaId); + Log.d(TAG, "playFolderItem: mediaId=" + mediaId); + + if (Flags.browsingRefactor()) { + if (!haveMediaBrowser(mBrowsingPlayerId)) { + Log.e( + TAG, + "playFolderItem: Do not have the a browsable player with ID " + + mBrowsingPlayerId); + return; + } - if (!mediaId.matches(BROWSE_ID_PATTERN)) { - // This should never happen since we control the media ID's reported - Log.wtf(TAG, "playFolderItem: mediaId didn't match pattern: mediaId=" + mediaId); - } + MediaBrowserWrapper wrapper = mMediaBrowserWrappers.get(mBrowsingPlayerId); + wrapper.playItem(mediaId); + } else { + if (!mediaId.matches(BROWSE_ID_PATTERN)) { + // This should never happen since we control the media ID's reported + Log.wtf(TAG, "playFolderItem: mediaId didn't match pattern: mediaId=" + mediaId); + } - int playerIndex = Integer.parseInt(mediaId.substring(0, 2)); - if (!haveMediaBrowser(playerIndex)) { - e("playFolderItem: Do not have the a browsable player with ID " + playerIndex); - return; - } + int playerIndex = Integer.parseInt(mediaId.substring(0, 2)); + if (!haveMediaBrowser(playerIndex)) { + e("playFolderItem: Do not have the a browsable player with ID " + playerIndex); + return; + } - BrowsedPlayerWrapper wrapper = mBrowsablePlayers.get(playerIndex); - String itemId = mediaId.substring(2); - if (TextUtils.isEmpty(itemId)) { - itemId = wrapper.getRootId(); + BrowsedPlayerWrapper wrapper = mBrowsablePlayers.get(playerIndex); + String itemId = mediaId.substring(2); if (TextUtils.isEmpty(itemId)) { - e("playFolderItem: Failed to start playback with an empty media id."); - return; + itemId = wrapper.getRootId(); + if (TextUtils.isEmpty(itemId)) { + e("playFolderItem: Failed to start playback with an empty media id."); + return; + } + Log.i( + TAG, + "playFolderItem: Empty media id, trying with the root id for " + + wrapper.getPackageName()); } - Log.i( - TAG, - "playFolderItem: Empty media id, trying with the root id for " - + wrapper.getPackageName()); + wrapper.playItem(itemId); } - wrapper.playItem(itemId); } - /** - * Calls {@code cb} with the list of browsable players as folder items. - * - *

As browsable players are subdirectories of the root Bluetooth player, the list always - * contains all the browsable players. - * - *

See {@link #getFolderItems}. - */ + /** Calls {@code cb} with the list of browsable players as folder items. */ void getFolderItemsMediaPlayerList(GetFolderItemsCallback cb) { - d("getFolderItemsMediaPlayerList: Sending Media Player list for root directory"); + Log.d(TAG, "getFolderItemsMediaPlayerList: Sending Media Player list for root directory"); ArrayList playerList = new ArrayList(); - for (BrowsedPlayerWrapper player : mBrowsablePlayers.values()) { + if (Flags.browsingRefactor()) { + for (MediaBrowserWrapper browser : mMediaBrowserWrappers.values()) { + + String displayName = Util.getDisplayName(mContext, browser.getPackageName()); + int id = mMediaPlayerIds.get(browser.getPackageName()); + + Log.d(TAG, "getFolderItemsMediaPlayerList: Adding player " + displayName); + Folder playerFolder = new Folder(String.format("%02d", id), false, displayName); + playerList.add(new ListItem(playerFolder)); + } + } else { + for (BrowsedPlayerWrapper player : mBrowsablePlayers.values()) { - String displayName = Util.getDisplayName(mContext, player.getPackageName()); - int id = mMediaPlayerIds.get(player.getPackageName()); + String displayName = Util.getDisplayName(mContext, player.getPackageName()); + int id = mMediaPlayerIds.get(player.getPackageName()); - d("getFolderItemsMediaPlayerList: Adding player " + displayName); - Folder playerFolder = new Folder(String.format("%02d", id), false, displayName); - playerList.add(new ListItem(playerFolder)); + Log.d(TAG, "getFolderItemsMediaPlayerList: Adding player " + displayName); + Folder playerFolder = new Folder(String.format("%02d", id), false, displayName); + playerList.add(new ListItem(playerFolder)); + } } cb.run("", playerList); return; @@ -574,18 +653,16 @@ public class MediaPlayerList { /** * Calls {@code cb} with a list of browsable folders. * - *

If {@code mediaId} is empty, {@code cb} will be called with all the browsable players as - * they are subdirectories of the root Bluetooth player. + *

If {@code mediaId} is empty, {@code cb} will be called with all the browsable players. * - *

If {@code mediaId} corresponds to a known {@link BrowsedPlayerWrapper}, {@code cb} will be - * called with the folder items list of the {@link BrowsedPlayerWrapper}. + *

If {@code mediaId} corresponds to a known {@link MediaBrowserWrapper}, {@code cb} will be + * called with the folder items list of the {@link MediaBrowserWrapper}. */ public void getFolderItems(int playerId, String mediaId, GetFolderItemsCallback cb) { - // The playerId is unused since we always assume the remote device is using the - // Bluetooth Player. - d("getFolderItems(): playerId=" + playerId + ", mediaId=" + mediaId); - /** M: Fix PTS AVRCP/TG/MCN/CB/BI-02-C fail @{ */ - if (Utils.isPtsTestMode()) { + Log.d(TAG, "getFolderItems(): playerId=" + playerId + ", mediaId=" + mediaId); + + if (!Flags.browsingRefactor() && Utils.isPtsTestMode()) { + /** M: Fix PTS AVRCP/TG/MCN/CB/BI-02-C fail @{ */ d("PTS test mode: getFolderItems"); BrowsedPlayerWrapper wrapper = mBrowsablePlayers.get(BLUETOOTH_PLAYER_ID + 1); String itemId = mediaId; @@ -603,10 +680,10 @@ public class MediaPlayerList { cb.run(mediaId, results); }); return; + /** + * @} + */ } - /** - * @} - */ // The device is requesting the content of the root folder. This folder contains a list of // Browsable Media Players displayed as folders with their contents contained within. @@ -615,44 +692,57 @@ public class MediaPlayerList { return; } - if (!mediaId.matches(BROWSE_ID_PATTERN)) { - // This should never happen since we control the media ID's reported - Log.wtf(TAG, "getFolderItems: mediaId didn't match pattern: mediaId=" + mediaId); - } + if (Flags.browsingRefactor()) { + if (mMediaBrowserWrappers.containsKey(playerId)) { + MediaBrowserWrapper wrapper = mMediaBrowserWrappers.get(playerId); + wrapper.getFolderItems( + mediaId, + (id, results) -> { + cb.run(mediaId, results); + }); + } else { + cb.run(mediaId, new ArrayList()); + } + } else { + if (!mediaId.matches(BROWSE_ID_PATTERN)) { + // This should never happen since we control the media ID's reported + Log.wtf(TAG, "getFolderItems: mediaId didn't match pattern: mediaId=" + mediaId); + } - int playerIndex = Integer.parseInt(mediaId.substring(0, 2)); - String itemId = mediaId.substring(2); + int playerIndex = Integer.parseInt(mediaId.substring(0, 2)); + String itemId = mediaId.substring(2); - // TODO (apanicke): Add timeouts for looking up folder items since media browsers don't - // have to respond. - if (haveMediaBrowser(playerIndex)) { - BrowsedPlayerWrapper wrapper = mBrowsablePlayers.get(playerIndex); - if (itemId.equals("")) { - Log.i(TAG, "Empty media id, getting the root for " + wrapper.getPackageName()); - itemId = wrapper.getRootId(); - } + // TODO (apanicke): Add timeouts for looking up folder items since media browsers don't + // have to respond. + if (haveMediaBrowser(playerIndex)) { + BrowsedPlayerWrapper wrapper = mBrowsablePlayers.get(playerIndex); + if (itemId.equals("")) { + Log.i(TAG, "Empty media id, getting the root for " + wrapper.getPackageName()); + itemId = wrapper.getRootId(); + } - wrapper.getFolderItems( - itemId, - (status, id, results) -> { - if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) { - cb.run(mediaId, new ArrayList()); - return; - } + wrapper.getFolderItems( + itemId, + (status, id, results) -> { + if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) { + cb.run(mediaId, new ArrayList()); + return; + } - String playerPrefix = String.format("%02d", playerIndex); - for (ListItem item : results) { - if (item.isFolder) { - item.folder.mediaId = playerPrefix.concat(item.folder.mediaId); - } else { - item.song.mediaId = playerPrefix.concat(item.song.mediaId); + String playerPrefix = String.format("%02d", playerIndex); + for (ListItem item : results) { + if (item.isFolder) { + item.folder.mediaId = playerPrefix.concat(item.folder.mediaId); + } else { + item.song.mediaId = playerPrefix.concat(item.song.mediaId); + } } - } - cb.run(mediaId, results); - }); - return; - } else { - cb.run(mediaId, new ArrayList()); + cb.run(mediaId, results); + }); + return; + } else { + cb.run(mediaId, new ArrayList()); + } } } @@ -722,6 +812,43 @@ public class MediaPlayerList { return addMediaPlayer(MediaControllerFactory.wrap(controller)); } + /** Retrieves a list of all packages that both are browsable and play audio */ + List getValidBrowsablePlayersPackages() { + + Intent intentPlayer = new Intent(Intent.ACTION_VIEW); + Intent intentBrowsable = + new Intent(android.service.media.MediaBrowserService.SERVICE_INTERFACE); + + Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1"); + intentPlayer.setDataAndType(uri, "audio/*"); + List audioPlayerList = + mContext.getApplicationContext() + .getPackageManager() + .queryIntentActivities(intentPlayer, 0); + + if (Flags.keepStoppedMediaBrowserService()) { + // Don't query stopped apps, that would end up unstopping them + intentBrowsable.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); + } + List browsablePlayerList = + mContext.getApplicationContext() + .getPackageManager() + .queryIntentServices(intentBrowsable, PackageManager.MATCH_ALL); + + List validBrowsablePackagesList = new ArrayList<>(); + for (ResolveInfo browsablePlayerInfo : browsablePlayerList) { + for (ResolveInfo audioPlayerInfo : audioPlayerList) { + if (audioPlayerInfo.activityInfo.packageName != null + && audioPlayerInfo.activityInfo.packageName.equals( + browsablePlayerInfo.serviceInfo.packageName)) { + validBrowsablePackagesList.add(browsablePlayerInfo); + break; + } + } + } + return validBrowsablePackagesList; + } + /** Returns true if {@code packageName} is present in {@link #mMediaPlayerIds}. */ boolean havePlayerId(String packageName) { if (packageName == null) return false; @@ -745,7 +872,11 @@ public class MediaPlayerList { /** Returns true if {@code playerId} is present in {@link #mBrowsablePlayers}. */ boolean haveMediaBrowser(int playerId) { - return mBrowsablePlayers.containsKey(playerId); + if (Flags.browsingRefactor()) { + return mMediaBrowserWrappers.containsKey(playerId); + } else { + return mBrowsablePlayers.containsKey(playerId); + } } /** @@ -950,17 +1081,48 @@ public class MediaPlayerList { if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) return; String packageName = intent.getData().getSchemeSpecificPart(); - if (haveMediaPlayer(packageName)) { - removeMediaPlayer(mMediaPlayerIds.get(packageName)); + Integer playerId = mMediaPlayerIds.get(packageName); + if (playerId == null) { + return; + } + if (haveMediaPlayer(playerId)) { + removeMediaPlayer(playerId); + } + if (Flags.browsingRefactor()) { + if (haveMediaBrowser(playerId)) { + Log.i(TAG, "package removed from browsable list: " + packageName); + mMediaBrowserWrappers.get(playerId).disconnect(); + mMediaBrowserWrappers.remove(playerId); + sendFolderUpdate(true, false, false); + } } } else if (action.equals(Intent.ACTION_PACKAGE_ADDED) || action.equals(Intent.ACTION_PACKAGE_CHANGED)) { String packageName = intent.getData().getSchemeSpecificPart(); - if (packageName != null) { - Log.d(TAG, "Name of package changed: " + packageName); - // TODO (apanicke): Handle either updating or adding the new package. - // Check if its browsable and send the UIDS changed to update the - // root folder + if (packageName == null) { + return; + } + if (!Flags.browsingRefactor()) { + return; + } + for (ResolveInfo info : getValidBrowsablePlayersPackages()) { + + // Check if added package is browsable + if (!info.serviceInfo.packageName.equals(packageName)) { + continue; + } + // Add it to the existing list + MediaBrowserWrapper wrapper = + new MediaBrowserWrapper( + mContext, mLooper, packageName, info.serviceInfo.name); + if (havePlayerId(packageName)) { + continue; + } + Log.i(TAG, "package added to browsable list: " + packageName); + int mediaId = getFreeMediaPlayerId(); + mMediaPlayerIds.put(packageName, mediaId); + mMediaBrowserWrappers.put(mediaId, wrapper); + sendFolderUpdate(true, false, false); } } } @@ -1194,10 +1356,18 @@ public class MediaPlayerList { sb.append("\n"); } - sb.append("List of Browsers: size=" + mBrowsablePlayers.size() + "\n"); - for (BrowsedPlayerWrapper player : mBrowsablePlayers.values()) { - sb.append(player.toString().replaceAll("(?m)^", " ")); - sb.append("\n"); + if (Flags.browsingRefactor()) { + sb.append("List of Browsers: size=" + mMediaBrowserWrappers.size() + "\n"); + for (MediaBrowserWrapper player : mMediaBrowserWrappers.values()) { + sb.append(player.toString().replaceAll("(?m)^", " ")); + sb.append("\n"); + } + } else { + sb.append("List of Browsers: size=" + mBrowsablePlayers.size() + "\n"); + for (BrowsedPlayerWrapper player : mBrowsablePlayers.values()) { + sb.append(player.toString().replaceAll("(?m)^", " ")); + sb.append("\n"); + } } mActivePlayerLogger.dump(sb); -- GitLab From f04702816d4c6d665f1ca8b5843155288784ab0a Mon Sep 17 00:00:00 2001 From: Nitin Jadhav Date: Thu, 6 Jun 2024 08:42:50 +0000 Subject: [PATCH 0018/1446] Flag to maintain call index after conference disconnect. Bug: 345380335 Bug: 315241296 Test: mmm packages/modules/Bluetooth Flag: com.android.bluetooth.flags.maintain_call_index_after_conference Change-Id: I6bdaa1934ff2a02d86276b9f27a50e9c566de62d --- flags/hfp.aconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/flags/hfp.aconfig b/flags/hfp.aconfig index 45e20865794..2c17a7fbcaf 100644 --- a/flags/hfp.aconfig +++ b/flags/hfp.aconfig @@ -126,3 +126,13 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "maintain_call_index_after_conference" + namespace: "bluetooth" + description: "Avoid change of clcc call index after call disconnects from conference" + bug: "345380335" + metadata { + purpose: PURPOSE_BUGFIX + } +} -- GitLab From f7600ea2eb4b0fcde592e5bc3d9aa860c58cb7fc Mon Sep 17 00:00:00 2001 From: Jakub Rotkiewicz Date: Wed, 29 May 2024 13:36:23 +0000 Subject: [PATCH 0019/1446] btif_av: access peers_ only from BtifAvSource/Sink This CL adds mutexes to protect peers_ in BtifAvSource/Sink. It also moves the invocation of btif_debug_av_peer_dump inside BtifAvSource/Sink classes. The Peers() methods are removed as they allowed nullpointer dereference in some scenarios. As peers_ are protected by mutex there is no need to handle src_do_suspend_in_main_thread in main thread. Bug: 300211201 Flag: Exempt, mechanical change only Test: mmm packages/modules/Bluetooth Change-Id: I509a41bff0c6200e11dc7c69705f942590e290a8 --- system/btif/src/btif_av.cc | 150 +++++++++++++++++++++++++------------ 1 file changed, 102 insertions(+), 48 deletions(-) diff --git a/system/btif/src/btif_av.cc b/system/btif/src/btif_av.cc index c8211c90552..0ea9abb27d1 100644 --- a/system/btif/src/btif_av.cc +++ b/system/btif/src/btif_av.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -595,8 +596,22 @@ class BtifAvSource { peer_address, codec_preferences, std::move(peer_ready_promise)); } - const std::map& Peers() const { return peers_; } + /** + * Get number of saved peers. + */ + int GetPeersCount() const { + std::lock_guard lock(btifavsource_peers_lock_); + return peers_.size(); + } + /** + * Dispatch SUSPEND or STOP A2DP stream event on all peer devices. + * Returns true if succeeded. + * @param event SUSPEND or STOP event + */ + void DispatchSuspendStreamEvent(btif_av_sm_event_t event); + + void DumpPeersInfo(int fd); void RegisterAllBtaHandles(); void DeregisterAllBtaHandles(); void BtaHandleRegistered(uint8_t peer_id, tBTA_AV_HNDL bta_handle); @@ -615,9 +630,8 @@ class BtifAvSource { std::set silenced_peers_; RawAddress active_peer_; std::map peer_id2bta_handle_; - std::mutex mutex_; // protect for BtifAvSource::peers_ - std::recursive_mutex btifavsource_peer_lock_; + mutable std::recursive_mutex btifavsource_peers_lock_; }; class BtifAvSink { @@ -752,8 +766,15 @@ class BtifAvSink { active_peer_ = RawAddress::kEmpty; } - const std::map& Peers() const { return peers_; } + /** + * Get number of saved peers. + */ + int GetPeersCount() const { + std::lock_guard lock(btifavsink_peers_lock_); + return peers_.size(); + } + void DumpPeersInfo(int fd); void RegisterAllBtaHandles(); void DeregisterAllBtaHandles(); void BtaHandleRegistered(uint8_t peer_id, tBTA_AV_HNDL bta_handle); @@ -770,6 +791,8 @@ class BtifAvSink { std::map peers_; RawAddress active_peer_; std::map peer_id2bta_handle_; + // protect for BtifAvSink::peers_ + mutable std::recursive_mutex btifavsink_peers_lock_; }; /***************************************************************************** @@ -803,6 +826,7 @@ static void btif_av_handle_event(uint8_t peer_sep, const RawAddress& peer_address, tBTA_AV_HNDL bta_handle, const BtifAvEvent& btif_av_event); +static void btif_debug_av_peer_dump(int fd, const BtifAvPeer& peer); static void btif_report_connection_state(const RawAddress& peer_address, btav_connection_state_t state, const bt_status_t status, @@ -1235,6 +1259,7 @@ BtifAvPeer* BtifAvSource::FindPeer(const RawAddress& peer_address) { } BtifAvPeer* BtifAvSource::FindPeerByHandle(tBTA_AV_HNDL bta_handle) { + std::lock_guard lock(btifavsource_peers_lock_); for (auto it : peers_) { BtifAvPeer* peer = it.second; if (peer->BtaHandle() == bta_handle) { @@ -1245,6 +1270,7 @@ BtifAvPeer* BtifAvSource::FindPeerByHandle(tBTA_AV_HNDL bta_handle) { } BtifAvPeer* BtifAvSource::FindPeerByPeerId(uint8_t peer_id) { + std::lock_guard lock(btifavsource_peers_lock_); for (auto it : peers_) { BtifAvPeer* peer = it.second; if (peer->PeerId() == peer_id) { @@ -1256,7 +1282,7 @@ BtifAvPeer* BtifAvSource::FindPeerByPeerId(uint8_t peer_id) { BtifAvPeer* BtifAvSource::FindOrCreatePeer(const RawAddress& peer_address, tBTA_AV_HNDL bta_handle) { - std::unique_lock lock1(mutex_); + std::lock_guard lock(btifavsource_peers_lock_); log::verbose("peer={} bta_handle=0x{:x}", peer_address, bta_handle); BtifAvPeer* peer = FindPeer(peer_address); @@ -1304,6 +1330,7 @@ BtifAvPeer* BtifAvSource::FindOrCreatePeer(const RawAddress& peer_address, } bool BtifAvSource::AllowedToConnect(const RawAddress& peer_address) const { + std::lock_guard lock(btifavsource_peers_lock_); int connected = 0; if (!com::android::bluetooth::flags::a2dp_concurrent_source_sink() && @@ -1339,26 +1366,60 @@ bool BtifAvSource::AllowedToConnect(const RawAddress& peer_address) const { if (!com::android::bluetooth::flags::a2dp_concurrent_source_sink() && btif_av_src_sink_coexist_enabled() && btif_av_both_enable()) { log::info("connected={}, max_connected_peers_={}, sink_peers={}", connected, - max_connected_peers_, (int)btif_av_sink.Peers().size()); + max_connected_peers_, btif_av_sink.GetPeersCount()); /* if source device connected, don't connect sink device */ - if (connected >= max_connected_peers_ || !btif_av_sink.Peers().empty()) { + if (connected >= max_connected_peers_ || + btif_av_sink.GetPeersCount() != 0) { return false; } else { return true; } } if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) { - const int sink_connected_peers_size = (int)btif_av_sink.Peers().size(); + const int sink_connected_peers_size = btif_av_sink.GetPeersCount(); log::info( "connected={}, max_connected_peers_={}, sink_connected_peers_size={}", - connected, max_connected_peers_, (int)btif_av_sink.Peers().size()); + connected, max_connected_peers_, btif_av_sink.GetPeersCount()); return ((connected + sink_connected_peers_size) < max_connected_peers_); } return (connected < max_connected_peers_); } +void BtifAvSource::DumpPeersInfo(int fd) { + std::lock_guard lock(btifavsource_peers_lock_); + for (auto it : peers_) { + const BtifAvPeer* peer = it.second; + if (peer != nullptr) { + btif_debug_av_peer_dump(fd, *peer); + } + } +} + +void BtifAvSource::DispatchSuspendStreamEvent(btif_av_sm_event_t event) { + std::lock_guard lock(btifavsource_peers_lock_); + if (event != BTIF_AV_SUSPEND_STREAM_REQ_EVT && + event != BTIF_AV_STOP_STREAM_REQ_EVT) { + log::error("Invalid event: {} id: {}", dump_av_sm_event_name(event), + (int)event); + return; + } + bool av_stream_idle = true; + for (auto it : peers_) { + const BtifAvPeer* peer = it.second; + if (peer->StateMachine().StateId() == BtifAvStateMachine::kStateStarted) { + btif_av_source_dispatch_sm_event(peer->PeerAddress(), event); + av_stream_idle = false; + } + } + + if (av_stream_idle) { + btif_a2dp_on_stopped(nullptr, A2dpType::kSource); + } +} + void BtifAvSource::DeleteIdlePeers() { + std::lock_guard lock(btifavsource_peers_lock_); for (auto it = peers_.begin(); it != peers_.end();) { BtifAvPeer* peer = it->second; auto prev_it = it++; @@ -1372,6 +1433,7 @@ void BtifAvSource::DeleteIdlePeers() { } void BtifAvSource::CleanupAllPeers() { + std::lock_guard lock(btifavsource_peers_lock_); log::info(""); while (!peers_.empty()) { @@ -1418,6 +1480,7 @@ void BtifAvSource::BtaHandleRegistered(uint8_t peer_id, } BtifAvPeer* BtifAvSource::popPeer(const RawAddress& peer_address) { + std::lock_guard lock(btifavsource_peers_lock_); auto it = peers_.find(peer_address); if (it == peers_.end()) return nullptr; BtifAvPeer* peer = it->second; @@ -1428,6 +1491,7 @@ BtifAvPeer* BtifAvSource::popPeer(const RawAddress& peer_address) { } void BtifAvSource::AddPeer(BtifAvPeer* peer) { + std::lock_guard lock(btifavsource_peers_lock_); log::info("peer={}, state={}", peer->PeerAddress(), peer->StateMachine().StateId()); peers_.insert(std::make_pair(peer->PeerAddress(), peer)); @@ -1488,6 +1552,7 @@ BtifAvPeer* BtifAvSink::FindPeer(const RawAddress& peer_address) { } BtifAvPeer* BtifAvSink::FindPeerByHandle(tBTA_AV_HNDL bta_handle) { + std::lock_guard lock(btifavsink_peers_lock_); for (auto it : peers_) { BtifAvPeer* peer = it.second; if (peer->BtaHandle() == bta_handle) { @@ -1498,6 +1563,7 @@ BtifAvPeer* BtifAvSink::FindPeerByHandle(tBTA_AV_HNDL bta_handle) { } BtifAvPeer* BtifAvSink::FindPeerByPeerId(uint8_t peer_id) { + std::lock_guard lock(btifavsink_peers_lock_); for (auto it : peers_) { BtifAvPeer* peer = it.second; if (peer->PeerId() == peer_id) { @@ -1509,6 +1575,7 @@ BtifAvPeer* BtifAvSink::FindPeerByPeerId(uint8_t peer_id) { BtifAvPeer* BtifAvSink::FindOrCreatePeer(const RawAddress& peer_address, tBTA_AV_HNDL bta_handle) { + std::lock_guard lock(btifavsink_peers_lock_); log::verbose("peer={} bta_handle=0x{:x}", peer_address, bta_handle); BtifAvPeer* peer = FindPeer(peer_address); @@ -1556,7 +1623,18 @@ BtifAvPeer* BtifAvSink::FindOrCreatePeer(const RawAddress& peer_address, return peer; } +void BtifAvSink::DumpPeersInfo(int fd) { + std::lock_guard lock(btifavsink_peers_lock_); + for (auto it : peers_) { + const BtifAvPeer* peer = it.second; + if (peer != nullptr) { + btif_debug_av_peer_dump(fd, *peer); + } + } +} + bool BtifAvSink::AllowedToConnect(const RawAddress& peer_address) const { + std::lock_guard lock(btifavsink_peers_lock_); int connected = 0; if (!com::android::bluetooth::flags::a2dp_concurrent_source_sink() && @@ -1600,14 +1678,14 @@ bool BtifAvSink::AllowedToConnect(const RawAddress& peer_address) const { if (!com::android::bluetooth::flags::a2dp_concurrent_source_sink() && btif_av_both_enable()) { log::info("connected={}, max_connected_peers_={}, source_peers={}", - connected, max_connected_peers_, - (int)btif_av_source.Peers().size()); + connected, max_connected_peers_, btif_av_source.GetPeersCount()); /* if source device connected, don't connect sink device */ - return (connected < max_connected_peers_) && btif_av_source.Peers().empty(); + return (connected < max_connected_peers_) && + (btif_av_source.GetPeersCount() == 0); } if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) { - const int source_connected_peers_size = (int)btif_av_source.Peers().size(); + const int source_connected_peers_size = btif_av_source.GetPeersCount(); log::info( "connected={}, max_connected_peers_={}, source_connected_peers_size={}", connected, max_connected_peers_, source_connected_peers_size); @@ -1617,6 +1695,7 @@ bool BtifAvSink::AllowedToConnect(const RawAddress& peer_address) const { } void BtifAvSink::DeleteIdlePeers() { + std::lock_guard lock(btifavsink_peers_lock_); for (auto it = peers_.begin(); it != peers_.end();) { BtifAvPeer* peer = it->second; auto prev_it = it++; @@ -1630,6 +1709,7 @@ void BtifAvSink::DeleteIdlePeers() { } void BtifAvSink::CleanupAllPeers() { + std::lock_guard lock(btifavsink_peers_lock_); log::info(""); while (!peers_.empty()) { @@ -1675,6 +1755,7 @@ void BtifAvSink::BtaHandleRegistered(uint8_t peer_id, tBTA_AV_HNDL bta_handle) { } BtifAvPeer* BtifAvSink::popPeer(const RawAddress& peer_address) { + std::lock_guard lock(btifavsink_peers_lock_); auto it = peers_.find(peer_address); if (it == peers_.end()) return nullptr; BtifAvPeer* peer = it->second; @@ -1685,6 +1766,7 @@ BtifAvPeer* BtifAvSink::popPeer(const RawAddress& peer_address) { } void BtifAvSink::AddPeer(BtifAvPeer* peer) { + std::lock_guard lock(btifavsink_peers_lock_); log::info("peer={}, state={}", peer->PeerAddress(), peer->StateMachine().StateId()); peers_.insert(std::make_pair(peer->PeerAddress(), peer)); @@ -3115,12 +3197,12 @@ static BtifAvPeer* btif_av_handle_both_peer(uint8_t peer_sep, if (!com::android::bluetooth::flags::a2dp_concurrent_source_sink()) { btif_av_source.SetInvalidPeerCheck(true); } - if (!btif_av_source.Peers().empty()) { + if (btif_av_source.GetPeersCount() != 0) { log::verbose( "peer_sep invalid, and already has sink peer, so try create a " "new sink peer"); peer = btif_av_source.FindOrCreatePeer(peer_address, bta_handle); - } else if (!btif_av_sink.Peers().empty()) { + } else if (btif_av_sink.GetPeersCount() != 0) { log::verbose( "peer_sep invalid, and already has source peer, so try create " "a new source peer"); @@ -3832,27 +3914,6 @@ void btif_av_stream_start_with_latency(bool use_latency_mode) { btif_av_event)); } -static void src_do_suspend_in_main_thread(btif_av_sm_event_t event) { - if (event != BTIF_AV_SUSPEND_STREAM_REQ_EVT && - event != BTIF_AV_STOP_STREAM_REQ_EVT) - return; - auto src_do_stream_suspend = [](btif_av_sm_event_t event) { - bool is_idle = true; - for (auto it : btif_av_source.Peers()) { - const BtifAvPeer* peer = it.second; - if (peer->StateMachine().StateId() == BtifAvStateMachine::kStateStarted) { - btif_av_source_dispatch_sm_event(peer->PeerAddress(), event); - is_idle = false; - } - } - if (is_idle) { - btif_a2dp_on_stopped(nullptr, A2dpType::kSource); - } - }; - // switch to main thread to prevent a race condition of accessing peers - do_in_main_thread(FROM_HERE, base::BindOnce(src_do_stream_suspend, event)); -} - void btif_av_stream_stop(const RawAddress& peer_address) { log::info("peer={}", peer_address); @@ -3863,7 +3924,7 @@ void btif_av_stream_stop(const RawAddress& peer_address) { // The active peer might have changed and we might be in the process // of reconfiguring the stream. We need to stop the appropriate peer(s). - src_do_suspend_in_main_thread(BTIF_AV_STOP_STREAM_REQ_EVT); + btif_av_source.DispatchSuspendStreamEvent(BTIF_AV_STOP_STREAM_REQ_EVT); } void btif_av_stream_suspend(void) { @@ -3871,7 +3932,7 @@ void btif_av_stream_suspend(void) { // The active peer might have changed and we might be in the process // of reconfiguring the stream. We need to suspend the appropriate peer(s). - src_do_suspend_in_main_thread(BTIF_AV_SUSPEND_STREAM_REQ_EVT); + btif_av_source.DispatchSuspendStreamEvent(BTIF_AV_SUSPEND_STREAM_REQ_EVT); } void btif_av_stream_start_offload(void) { @@ -4199,12 +4260,8 @@ static void btif_debug_av_source_dump(int fd) { if (!enabled) return; dprintf(fd, " Active peer: %s\n", ADDRESS_TO_LOGGABLE_CSTR(btif_av_source.ActivePeer())); - for (auto it : btif_av_source.Peers()) { - const BtifAvPeer* peer = it.second; - if (peer != nullptr) { - btif_debug_av_peer_dump(fd, *peer); - } - } + dprintf(fd, " Peers:\n"); + btif_av_source.DumpPeersInfo(fd); } static void btif_debug_av_sink_dump(int fd) { @@ -4215,10 +4272,7 @@ static void btif_debug_av_sink_dump(int fd) { dprintf(fd, " Active peer: %s\n", ADDRESS_TO_LOGGABLE_CSTR(btif_av_sink.ActivePeer())); dprintf(fd, " Peers:\n"); - for (auto it : btif_av_sink.Peers()) { - const BtifAvPeer* peer = it.second; - btif_debug_av_peer_dump(fd, *peer); - } + btif_av_sink.DumpPeersInfo(fd); } void btif_debug_av_dump(int fd) { -- GitLab From 0d0ce8597e1cd19affd50fa8d88843e3f62383ec Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Fri, 14 Jun 2024 11:31:29 -0700 Subject: [PATCH 0020/1446] system/rust: Update GATT packet definition to use 8[] for ATT values Bug: 331817295 Test: m com.android.btservices Test: atest --host libbluetooth_core_rs_test Flag: EXEMPT, mechanical refactor Change-Id: Ia8b5fbf470df7ed3d20fced5339beb136e3aa9ba --- system/rust/src/gatt/ffi.rs | 4 +- .../rust/src/gatt/server/att_server_bearer.rs | 104 +++++------------- .../rust/src/gatt/server/command_handler.rs | 11 +- system/rust/src/gatt/server/gatt_database.rs | 69 ++++++------ .../src/gatt/server/indication_handler.rs | 48 +++----- .../rust/src/gatt/server/request_handler.rs | 11 +- system/rust/src/gatt/server/services/gatt.rs | 18 +-- .../server/transactions/find_by_type_value.rs | 18 +-- .../helpers/att_filter_by_size_type.rs | 26 ++--- .../read_by_group_type_request.rs | 18 +-- .../transactions/read_by_type_request.rs | 16 +-- .../gatt/server/transactions/read_request.rs | 18 +-- .../gatt/server/transactions/write_request.rs | 14 +-- system/rust/src/packets.pdl | 22 ++-- system/rust/src/utils/packet.rs | 8 +- system/rust/tests/gatt_server_test.rs | 69 ++++++------ 16 files changed, 183 insertions(+), 291 deletions(-) diff --git a/system/rust/src/gatt/ffi.rs b/system/rust/src/gatt/ffi.rs index d5a9ec7a2d9..965383edef2 100644 --- a/system/rust/src/gatt/ffi.rs +++ b/system/rust/src/gatt/ffi.rs @@ -12,7 +12,7 @@ use tokio::task::spawn_local; use crate::{ do_in_rust_thread, - packets::{AttAttributeDataChild, AttBuilder, AttErrorCode, Serializable, SerializeError}, + packets::{AttBuilder, AttErrorCode, Serializable, SerializeError}, }; use super::{ @@ -438,7 +438,7 @@ fn send_response(_server_id: u8, conn_id: u16, trans_id: u32, status: u8, value: fn send_indication(_server_id: u8, handle: u16, conn_id: u16, value: &[u8]) { let handle = AttHandle(handle); let conn_id = ConnectionId(conn_id); - let value = AttAttributeDataChild::RawData(value.into()); + let value = value.into(); trace!("send_indication {handle:?}, {conn_id:?}"); diff --git a/system/rust/src/gatt/server/att_server_bearer.rs b/system/rust/src/gatt/server/att_server_bearer.rs index d2d732fc7a8..b6ba9c5ebba 100644 --- a/system/rust/src/gatt/server/att_server_bearer.rs +++ b/system/rust/src/gatt/server/att_server_bearer.rs @@ -19,8 +19,8 @@ use crate::{ opcode_types::{classify_opcode, OperationType}, }, packets::{ - AttAttributeDataChild, AttBuilder, AttChild, AttErrorCode, AttErrorResponseBuilder, - AttView, Packet, SerializeError, + AttBuilder, AttChild, AttErrorCode, AttErrorResponseBuilder, AttView, Packet, + SerializeError, }, utils::{owned_handle::OwnedHandle, packet::HACK_child_to_opcode}, }; @@ -118,7 +118,7 @@ impl WeakBoxRef<'_, AttServerBearer> { pub fn send_indication( &self, handle: AttHandle, - data: AttAttributeDataChild, + data: Vec, ) -> impl Future> { trace!("sending indication for handle {handle:?}"); @@ -143,7 +143,7 @@ impl WeakBoxRef<'_, AttServerBearer> { IndicationError::SendError(SendError::ConnectionDropped) })?; // finally, send, and wait for a response - indication_handler.send(handle, data, mtu, |packet| this.try_send_packet(packet)).await + indication_handler.send(handle, &data, mtu, |packet| this.try_send_packet(packet)).await } } @@ -238,8 +238,8 @@ mod test { }, }, packets::{ - AttAttributeDataBuilder, AttAttributeDataChild, AttHandleValueConfirmationBuilder, - AttOpcode, AttReadRequestBuilder, AttReadResponseBuilder, + AttHandleValueConfirmationBuilder, AttOpcode, AttReadRequestBuilder, + AttReadResponseBuilder, }, utils::{ packet::build_att_view_or_crash, @@ -389,14 +389,7 @@ mod test { resp, AttBuilder { opcode: AttOpcode::READ_RESPONSE, - _child_: AttReadResponseBuilder { - value: AttAttributeDataBuilder { - _child_: AttAttributeDataChild::RawData( - data.to_vec().into_boxed_slice() - ) - }, - } - .into() + _child_: AttReadResponseBuilder { value: data.into() }.into() } ); // assert no other replies were made @@ -414,10 +407,7 @@ mod test { // act: send an indication let pending_send = - spawn_local(conn.as_ref().send_indication( - VALID_HANDLE, - AttAttributeDataChild::RawData([1, 2, 3].into()), - )); + spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); assert_eq!(rx.recv().await.unwrap().opcode, AttOpcode::HANDLE_VALUE_INDICATION); assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); // and the confirmation @@ -438,10 +428,7 @@ mod test { // act: send the first indication let pending_send1 = - spawn_local(conn.as_ref().send_indication( - VALID_HANDLE, - AttAttributeDataChild::RawData([1, 2, 3].into()), - )); + spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); // wait for/capture the outgoing packet let sent1 = rx.recv().await.unwrap(); // send the response @@ -450,10 +437,7 @@ mod test { ); // send the second indication let pending_send2 = - spawn_local(conn.as_ref().send_indication( - VALID_HANDLE, - AttAttributeDataChild::RawData([1, 2, 3].into()), - )); + spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); // wait for/capture the outgoing packet let sent2 = rx.recv().await.unwrap(); // and the response @@ -479,14 +463,9 @@ mod test { // act: send two indications simultaneously let pending_send1 = - spawn_local(conn.as_ref().send_indication( - VALID_HANDLE, - AttAttributeDataChild::RawData([1, 2, 3].into()), - )); - let pending_send2 = spawn_local(conn.as_ref().send_indication( - ANOTHER_VALID_HANDLE, - AttAttributeDataChild::RawData([1, 2, 3].into()), - )); + spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); + let pending_send2 = + spawn_local(conn.as_ref().send_indication(ANOTHER_VALID_HANDLE, vec![1, 2, 3])); // assert: only one was initially sent assert_eq!(rx.recv().await.unwrap().opcode, AttOpcode::HANDLE_VALUE_INDICATION); assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); @@ -504,14 +483,9 @@ mod test { // act: send two indications simultaneously let pending_send1 = - spawn_local(conn.as_ref().send_indication( - VALID_HANDLE, - AttAttributeDataChild::RawData([1, 2, 3].into()), - )); - let pending_send2 = spawn_local(conn.as_ref().send_indication( - ANOTHER_VALID_HANDLE, - AttAttributeDataChild::RawData([1, 2, 3].into()), - )); + spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); + let pending_send2 = + spawn_local(conn.as_ref().send_indication(ANOTHER_VALID_HANDLE, vec![1, 2, 3])); // wait for/capture the outgoing packet let sent1 = rx.recv().await.unwrap(); // send response for the first one @@ -540,14 +514,9 @@ mod test { // act: send two indications simultaneously let pending_send1 = - spawn_local(conn.as_ref().send_indication( - VALID_HANDLE, - AttAttributeDataChild::RawData([1, 2, 3].into()), - )); - let pending_send2 = spawn_local(conn.as_ref().send_indication( - ANOTHER_VALID_HANDLE, - AttAttributeDataChild::RawData([1, 2, 3].into()), - )); + spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); + let pending_send2 = + spawn_local(conn.as_ref().send_indication(ANOTHER_VALID_HANDLE, vec![1, 2, 3])); // wait for/capture the outgoing packet let sent1 = rx.recv().await.unwrap(); // send response for the first one @@ -577,10 +546,7 @@ mod test { // arrange: a pending indication let (conn, mut rx) = open_connection(); let pending_send = - spawn_local(conn.as_ref().send_indication( - VALID_HANDLE, - AttAttributeDataChild::RawData([1, 2, 3].into()), - )); + spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); // act: drop the connection after the indication is sent rx.recv().await.unwrap(); @@ -602,12 +568,7 @@ mod test { conn.as_ref().handle_mtu_event(MtuEvent::OutgoingRequest).unwrap(); // act: try to send an indication with a large payload size - let _ = - try_await(conn.as_ref().send_indication( - VALID_HANDLE, - AttAttributeDataChild::RawData((1..50).collect()), - )) - .await; + let _ = try_await(conn.as_ref().send_indication(VALID_HANDLE, (1..50).collect())).await; // then resolve the MTU negotiation with a large MTU conn.as_ref().handle_mtu_event(MtuEvent::IncomingResponse(100)).unwrap(); @@ -625,12 +586,9 @@ mod test { // act: try to send an indication with a large payload size let pending_mtu = - try_await(conn.as_ref().send_indication( - VALID_HANDLE, - AttAttributeDataChild::RawData((1..50).collect()), - )) - .await - .unwrap_err(); + try_await(conn.as_ref().send_indication(VALID_HANDLE, (1..50).collect())) + .await + .unwrap_err(); // then resolve the MTU negotiation with a small MTU conn.as_ref().handle_mtu_event(MtuEvent::IncomingResponse(32)).unwrap(); @@ -664,21 +622,11 @@ mod test { block_on_locally(async { // arrange: an outstanding indication let (conn, mut rx) = open_connection(); - let _ = - try_await(conn.as_ref().send_indication( - VALID_HANDLE, - AttAttributeDataChild::RawData([1, 2, 3].into()), - )) - .await; + let _ = try_await(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])).await; rx.recv().await.unwrap(); // flush rx_queue // act: enqueue an indication with a large payload - let _ = - try_await(conn.as_ref().send_indication( - VALID_HANDLE, - AttAttributeDataChild::RawData((1..50).collect()), - )) - .await; + let _ = try_await(conn.as_ref().send_indication(VALID_HANDLE, (1..50).collect())).await; // then perform MTU negotiation to upgrade to a large MTU conn.as_ref().handle_mtu_event(MtuEvent::OutgoingRequest).unwrap(); conn.as_ref().handle_mtu_event(MtuEvent::IncomingResponse(512)).unwrap(); diff --git a/system/rust/src/gatt/server/command_handler.rs b/system/rust/src/gatt/server/command_handler.rs index a147584da99..763c68f7d09 100644 --- a/system/rust/src/gatt/server/command_handler.rs +++ b/system/rust/src/gatt/server/command_handler.rs @@ -24,7 +24,7 @@ impl AttCommandHandler { }; snapshotted_db.write_no_response_attribute( packet.get_handle().into(), - &packet.get_value().get_raw_payload().collect::>(), + &packet.get_value_iter().collect::>(), ); } _ => { @@ -47,10 +47,7 @@ mod test { test::test_att_db::TestAttDatabase, }, }, - packets::{ - AttAttributeDataBuilder, AttAttributeDataChild, AttErrorCode, AttErrorResponseBuilder, - AttOpcode, AttWriteCommandBuilder, - }, + packets::{AttErrorCode, AttErrorResponseBuilder, AttOpcode, AttWriteCommandBuilder}, utils::{packet::build_att_view_or_crash, task::block_on_locally}, }; @@ -71,9 +68,7 @@ mod test { // act: send write command let att_view = build_att_view_or_crash(AttWriteCommandBuilder { handle: AttHandle(3).into(), - value: AttAttributeDataBuilder { - _child_: AttAttributeDataChild::RawData(data.to_vec().into_boxed_slice()), - }, + value: data.into(), }); handler.process_packet(att_view.view()); diff --git a/system/rust/src/gatt/server/gatt_database.rs b/system/rust/src/gatt/server/gatt_database.rs index baffd177730..b1c688f0a78 100644 --- a/system/rust/src/gatt/server/gatt_database.rs +++ b/system/rust/src/gatt/server/gatt_database.rs @@ -521,7 +521,6 @@ mod test { mock_datastore::{MockDatastore, MockDatastoreEvents}, mock_raw_datastore::{MockRawDatastore, MockRawDatastoreEvents}, }, - packets::AttAttributeDataChild, utils::task::block_on_locally, }; @@ -578,11 +577,9 @@ mod test { ); assert_eq!( service_value, - AttAttributeDataChild::GattServiceDeclarationValue( - GattServiceDeclarationValueBuilder { uuid: SERVICE_TYPE.into() } - ) - .to_vec() - .map_err(|_| AttErrorCode::UNLIKELY_ERROR) + GattServiceDeclarationValueBuilder { uuid: SERVICE_TYPE.into() } + .to_vec() + .map_err(|_| AttErrorCode::UNLIKELY_ERROR) ); } @@ -717,22 +714,20 @@ mod test { assert_eq!( characteristic_decl, - AttAttributeDataChild::GattCharacteristicDeclarationValue( - GattCharacteristicDeclarationValueBuilder { - properties: GattCharacteristicPropertiesBuilder { - read: 1, - broadcast: 0, - write_without_response: 0, - write: 1, - notify: 0, - indicate: 1, - authenticated_signed_writes: 0, - extended_properties: 0, - }, - handle: CHARACTERISTIC_VALUE_HANDLE.into(), - uuid: CHARACTERISTIC_TYPE.into() - } - ) + GattCharacteristicDeclarationValueBuilder { + properties: GattCharacteristicPropertiesBuilder { + read: 1, + broadcast: 0, + write_without_response: 0, + write: 1, + notify: 0, + indicate: 1, + authenticated_signed_writes: 0, + extended_properties: 0, + }, + handle: CHARACTERISTIC_VALUE_HANDLE.into(), + uuid: CHARACTERISTIC_TYPE.into() + } .to_vec() .map_err(|_| AttErrorCode::UNLIKELY_ERROR) ); @@ -767,22 +762,20 @@ mod test { tokio_test::block_on(att_db.read_attribute(CHARACTERISTIC_DECLARATION_HANDLE)); assert_eq!( characteristic_decl, - AttAttributeDataChild::GattCharacteristicDeclarationValue( - GattCharacteristicDeclarationValueBuilder { - properties: GattCharacteristicPropertiesBuilder { - read: 1, - broadcast: 0, - write_without_response: 1, - write: 1, - notify: 0, - indicate: 1, - authenticated_signed_writes: 0, - extended_properties: 0, - }, - handle: CHARACTERISTIC_VALUE_HANDLE.into(), - uuid: CHARACTERISTIC_TYPE.into() - } - ) + GattCharacteristicDeclarationValueBuilder { + properties: GattCharacteristicPropertiesBuilder { + read: 1, + broadcast: 0, + write_without_response: 1, + write: 1, + notify: 0, + indicate: 1, + authenticated_signed_writes: 0, + extended_properties: 0, + }, + handle: CHARACTERISTIC_VALUE_HANDLE.into(), + uuid: CHARACTERISTIC_TYPE.into() + } .to_vec() .map_err(|_| AttErrorCode::UNLIKELY_ERROR) ); diff --git a/system/rust/src/gatt/server/indication_handler.rs b/system/rust/src/gatt/server/indication_handler.rs index c69a68f91c7..0a06003a7b2 100644 --- a/system/rust/src/gatt/server/indication_handler.rs +++ b/system/rust/src/gatt/server/indication_handler.rs @@ -8,8 +8,7 @@ use tokio::{ use crate::{ gatt::ids::AttHandle, - packets::{AttAttributeDataChild, AttChild, AttHandleValueIndicationBuilder, Serializable}, - utils::packet::build_att_data, + packets::{AttChild, AttHandleValueIndicationBuilder}, }; use super::{ @@ -52,17 +51,14 @@ impl IndicationHandler { pub async fn send( &mut self, handle: AttHandle, - data: AttAttributeDataChild, + data: &[u8], mtu: usize, send_packet: impl FnOnce(AttChild) -> Result<(), SendError>, ) -> Result<(), IndicationError> { - let data_size = data - .size_in_bits() - .map_err(SendError::SerializeError) - .map_err(IndicationError::SendError)?; + let data_size = data.len(); // As per Core Spec 5.3 Vol 3F 3.4.7.2, the indicated value must be at most // ATT_MTU-3 - if data_size > (mtu - 3) * 8 { + if data_size > (mtu - 3) { return Err(IndicationError::DataExceedsMtu { mtu: mtu - 3 }); } @@ -82,8 +78,7 @@ impl IndicationHandler { let _ = self.pending_confirmation.try_recv(); send_packet( - AttHandleValueIndicationBuilder { handle: handle.into(), value: build_att_data(data) } - .into(), + AttHandleValueIndicationBuilder { handle: handle.into(), value: data.into() }.into(), ) .map_err(IndicationError::SendError)?; @@ -138,10 +133,7 @@ mod test { const NONEXISTENT_HANDLE: AttHandle = AttHandle(2); const NON_INDICATE_HANDLE: AttHandle = AttHandle(3); const MTU: usize = 32; - - fn get_data() -> AttAttributeDataChild { - AttAttributeDataChild::RawData([1, 2, 3].into()) - } + const DATA: [u8; 3] = [1, 2, 3]; fn get_att_database() -> TestAttDatabase { TestAttDatabase::new(vec![ @@ -175,7 +167,7 @@ mod test { // act: send an indication spawn_local(async move { indication_handler - .send(HANDLE, get_data(), MTU, move |packet| { + .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) @@ -188,10 +180,7 @@ mod test { }; assert_eq!( indication, - AttHandleValueIndicationBuilder { - handle: HANDLE.into(), - value: build_att_data(get_data()), - } + AttHandleValueIndicationBuilder { handle: HANDLE.into(), value: DATA.into() } ); }); } @@ -205,7 +194,7 @@ mod test { // act: send an indication on a nonexistent handle let ret = indication_handler - .send(NONEXISTENT_HANDLE, get_data(), MTU, move |_| unreachable!()) + .send(NONEXISTENT_HANDLE, &DATA, MTU, move |_| unreachable!()) .await; // assert: that we failed with IndicationError::AttributeNotFound @@ -222,7 +211,7 @@ mod test { // act: send an indication on an attribute that does not support indications let ret = indication_handler - .send(NON_INDICATE_HANDLE, get_data(), MTU, move |_| unreachable!()) + .send(NON_INDICATE_HANDLE, &DATA, MTU, move |_| unreachable!()) .await; // assert: that we failed with IndicationError::IndicationsNotSupported @@ -241,7 +230,7 @@ mod test { // act: send an indication let pending_result = spawn_local(async move { indication_handler - .send(HANDLE, get_data(), MTU, move |packet| { + .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) @@ -267,7 +256,7 @@ mod test { // act: send an indication let pending_result = spawn_local(async move { indication_handler - .send(HANDLE, get_data(), MTU, move |packet| { + .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) @@ -299,7 +288,7 @@ mod test { // act: send an indication let pending_result = spawn_local(async move { indication_handler - .send(HANDLE, get_data(), MTU, move |packet| { + .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) @@ -334,7 +323,7 @@ mod test { let time_sent = Instant::now(); let pending_result = spawn_local(async move { indication_handler - .send(HANDLE, get_data(), MTU, move |packet| { + .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) @@ -365,14 +354,7 @@ mod test { IndicationHandler::new(get_att_database()); // act: send an indication with an ATT_MTU of 4 and data length of 3 - let res = indication_handler - .send( - HANDLE, - AttAttributeDataChild::RawData([1, 2, 3].into()), - 4, - move |_| unreachable!(), - ) - .await; + let res = indication_handler.send(HANDLE, &[1, 2, 3], 4, move |_| unreachable!()).await; // assert: that we got the expected error, indicating the max data size (not the // ATT_MTU, but ATT_MTU-3) diff --git a/system/rust/src/gatt/server/request_handler.rs b/system/rust/src/gatt/server/request_handler.rs index e6890803d00..74cbb7f3e0c 100644 --- a/system/rust/src/gatt/server/request_handler.rs +++ b/system/rust/src/gatt/server/request_handler.rs @@ -110,11 +110,8 @@ mod test { request_handler::AttRequestHandler, test::test_att_db::TestAttDatabase, }, - packets::{ - AttAttributeDataChild, AttReadRequestBuilder, AttReadResponseBuilder, - AttWriteResponseBuilder, - }, - utils::packet::{build_att_data, build_att_view_or_crash}, + packets::{AttReadRequestBuilder, AttReadResponseBuilder, AttWriteResponseBuilder}, + utils::packet::build_att_view_or_crash, }; #[test] @@ -139,9 +136,7 @@ mod test { // assert assert_eq!( response, - AttChild::AttReadResponse(AttReadResponseBuilder { - value: build_att_data(AttAttributeDataChild::RawData([1, 2, 3].into())) - }) + AttChild::AttReadResponse(AttReadResponseBuilder { value: [1, 2, 3].into() }) ); } diff --git a/system/rust/src/gatt/server/services/gatt.rs b/system/rust/src/gatt/server/services/gatt.rs index 5bb6ce5f894..6ba8e902382 100644 --- a/system/rust/src/gatt/server/services/gatt.rs +++ b/system/rust/src/gatt/server/services/gatt.rs @@ -135,7 +135,8 @@ impl GattDatabaseCallbacks for GattService { start_handle: (*range.start()).into(), end_handle: (*range.end()).into(), } - .into(), + .to_vec() + .unwrap(), ), ); } @@ -190,7 +191,7 @@ mod test { }, }, }, - packets::{AttAttributeDataChild, AttBuilder, AttChild}, + packets::{AttBuilder, AttChild}, utils::task::{block_on_locally, try_await}, }; @@ -369,11 +370,14 @@ mod test { let AttChild::AttHandleValueIndication(resp) = resp._child_ else { unreachable!(); }; - let AttAttributeDataChild::GattServiceChanged(resp) = resp.value._child_ else { - unreachable!(); - }; - assert_eq!(resp.start_handle.handle, 15); - assert_eq!(resp.end_handle.handle, 17); + assert_eq!( + Ok(resp.value.into()), + GattServiceChangedBuilder { + start_handle: AttHandle(15).into(), + end_handle: AttHandle(17).into(), + } + .to_vec() + ); }); } diff --git a/system/rust/src/gatt/server/transactions/find_by_type_value.rs b/system/rust/src/gatt/server/transactions/find_by_type_value.rs index 5a7cbb280a8..d3a463084ab 100644 --- a/system/rust/src/gatt/server/transactions/find_by_type_value.rs +++ b/system/rust/src/gatt/server/transactions/find_by_type_value.rs @@ -43,7 +43,7 @@ pub async fn handle_find_by_type_value_request( continue; } if let Ok(value) = db.read_attribute(handle).await { - if value == request.get_attribute_value().get_raw_payload().collect::>() { + if value == request.get_attribute_value_iter().collect::>() { // match found if !matches.push(AttributeHandleRangeBuilder { found_attribute_handle: handle.into(), @@ -84,8 +84,8 @@ mod test { test::test_att_db::TestAttDatabase, }, }, - packets::{AttAttributeDataChild, AttFindByTypeValueRequestBuilder}, - utils::packet::{build_att_data, build_view_or_crash}, + packets::AttFindByTypeValueRequestBuilder, + utils::packet::build_view_or_crash, }; use super::*; @@ -131,7 +131,7 @@ mod test { starting_handle: AttHandle(3).into(), ending_handle: AttHandle(5).into(), attribute_type: UUID.try_into().unwrap(), - attribute_value: build_att_data(AttAttributeDataChild::RawData(VALUE.into())), + attribute_value: VALUE.into(), }); let response = tokio_test::block_on(handle_find_by_type_value_request(att_view.view(), 128, &db)); @@ -193,7 +193,7 @@ mod test { starting_handle: AttHandle(3).into(), ending_handle: AttHandle(5).into(), attribute_type: UUID.try_into().unwrap(), - attribute_value: build_att_data(AttAttributeDataChild::RawData(VALUE.into())), + attribute_value: VALUE.into(), }); let response = tokio_test::block_on(handle_find_by_type_value_request(att_view.view(), 128, &db)); @@ -230,7 +230,7 @@ mod test { starting_handle: AttHandle(3).into(), ending_handle: AttHandle(1).into(), attribute_type: UUID.try_into().unwrap(), - attribute_value: build_att_data(AttAttributeDataChild::RawData(VALUE.into())), + attribute_value: VALUE.into(), }); let response = tokio_test::block_on(handle_find_by_type_value_request(att_view.view(), 128, &db)); @@ -264,7 +264,7 @@ mod test { starting_handle: AttHandle(4).into(), ending_handle: AttHandle(5).into(), attribute_type: UUID.try_into().unwrap(), - attribute_value: build_att_data(AttAttributeDataChild::RawData(VALUE.into())), + attribute_value: VALUE.into(), }); let response = tokio_test::block_on(handle_find_by_type_value_request(att_view.view(), 128, &db)); @@ -316,7 +316,7 @@ mod test { starting_handle: AttHandle(3).into(), ending_handle: AttHandle(4).into(), attribute_type: CHARACTERISTIC_UUID.try_into().unwrap(), - attribute_value: build_att_data(AttAttributeDataChild::RawData(VALUE.into())), + attribute_value: VALUE.into(), }); let response = tokio_test::block_on(handle_find_by_type_value_request(att_view.view(), 128, &db)); @@ -364,7 +364,7 @@ mod test { starting_handle: AttHandle(3).into(), ending_handle: AttHandle(4).into(), attribute_type: UUID.try_into().unwrap(), - attribute_value: build_att_data(AttAttributeDataChild::RawData(VALUE.into())), + attribute_value: VALUE.into(), }); let response = tokio_test::block_on(handle_find_by_type_value_request(att_view.view(), 5, &db)); diff --git a/system/rust/src/gatt/server/transactions/helpers/att_filter_by_size_type.rs b/system/rust/src/gatt/server/transactions/helpers/att_filter_by_size_type.rs index 52abe8c5c29..ac93459bcfa 100644 --- a/system/rust/src/gatt/server/transactions/helpers/att_filter_by_size_type.rs +++ b/system/rust/src/gatt/server/transactions/helpers/att_filter_by_size_type.rs @@ -4,7 +4,7 @@ use crate::{ core::uuid::Uuid, gatt::server::att_database::{AttAttribute, StableAttDatabase}, - packets::{AttAttributeDataChild, AttErrorCode}, + packets::AttErrorCode, }; /// An attribute and the value @@ -12,7 +12,7 @@ use crate::{ pub struct AttributeWithValue { /// The attribute pub attr: AttAttribute, - pub value: AttAttributeDataChild, + pub value: Vec, } /// Takes a StableAttDatabase, a range of handles, a target type, and a @@ -49,10 +49,7 @@ pub async fn filter_read_attributes_by_size_type( curr_elem_size = Some(value_size) } - out.push(AttributeWithValue { - attr, - value: AttAttributeDataChild::RawData(value.into_boxed_slice()), - }); + out.push(AttributeWithValue { attr, value }); } Err(err) => { if out.is_empty() { @@ -80,7 +77,6 @@ mod test { test::test_att_db::TestAttDatabase, }, }, - packets::AttAttributeDataChild, }; const UUID: Uuid = Uuid::new(1234); @@ -112,7 +108,7 @@ mod test { response.collect::>(), vec![AttributeWithValue { attr: db.find_attribute(AttHandle(3)).unwrap(), - value: AttAttributeDataChild::RawData([4, 5].into()) + value: vec![4, 5] }] ) } @@ -162,11 +158,11 @@ mod test { vec![ AttributeWithValue { attr: db.find_attribute(AttHandle(3)).unwrap(), - value: AttAttributeDataChild::RawData([4, 5].into()) + value: vec![4, 5], }, AttributeWithValue { attr: db.find_attribute(AttHandle(6)).unwrap(), - value: AttAttributeDataChild::RawData([6, 7].into()) + value: vec![6, 7], } ] ); @@ -216,7 +212,7 @@ mod test { response.collect::>(), vec![AttributeWithValue { attr: db.find_attribute(AttHandle(3)).unwrap(), - value: AttAttributeDataChild::RawData([4, 5].into()) + value: vec![4, 5], },] ); } @@ -247,7 +243,7 @@ mod test { response.collect::>(), vec![AttributeWithValue { attr: db.find_attribute(AttHandle(3)).unwrap(), - value: AttAttributeDataChild::RawData([4, 5].into()) + value: vec![4, 5], },] ); } @@ -340,7 +336,7 @@ mod test { response.collect::>(), vec![AttributeWithValue { attr: db.find_attribute(AttHandle(3)).unwrap(), - value: AttAttributeDataChild::RawData([4, 5, 6].into()) + value: vec![4, 5, 6], },] ); } @@ -391,11 +387,11 @@ mod test { vec![ AttributeWithValue { attr: db.find_attribute(AttHandle(3)).unwrap(), - value: AttAttributeDataChild::RawData([4, 5, 6].into()) + value: vec![4, 5, 6], }, AttributeWithValue { attr: db.find_attribute(AttHandle(5)).unwrap(), - value: AttAttributeDataChild::RawData([6, 7, 8].into()) + value: vec![6, 7, 8], } ] ); diff --git a/system/rust/src/gatt/server/transactions/read_by_group_type_request.rs b/system/rust/src/gatt/server/transactions/read_by_group_type_request.rs index 5e532220220..762b8ce1960 100644 --- a/system/rust/src/gatt/server/transactions/read_by_group_type_request.rs +++ b/system/rust/src/gatt/server/transactions/read_by_group_type_request.rs @@ -8,7 +8,7 @@ use crate::{ }, }, packets::{ - AttAttributeDataBuilder, AttChild, AttErrorCode, AttErrorResponseBuilder, AttOpcode, + AttChild, AttErrorCode, AttErrorResponseBuilder, AttOpcode, AttReadByGroupTypeDataElementBuilder, AttReadByGroupTypeRequestView, AttReadByGroupTypeResponseBuilder, ParseError, }, @@ -74,7 +74,7 @@ pub async fn handle_read_by_group_type_request( .expect("should never be None, since grouping UUID was validated earlier") .handle .into(), - value: AttAttributeDataBuilder { _child_: value }, + value: value.into(), }) { break; } @@ -104,8 +104,8 @@ mod test { test::test_att_db::TestAttDatabase, }, }, - packets::{AttAttributeDataChild, AttReadByGroupTypeRequestBuilder}, - utils::packet::{build_att_data, build_view_or_crash}, + packets::AttReadByGroupTypeRequestBuilder, + utils::packet::build_view_or_crash, }; use super::*; @@ -161,12 +161,12 @@ mod test { AttReadByGroupTypeDataElementBuilder { handle: AttHandle(3).into(), end_group_handle: AttHandle(4).into(), - value: build_att_data(AttAttributeDataChild::RawData([4, 5].into())), + value: [4, 5].into(), }, AttReadByGroupTypeDataElementBuilder { handle: AttHandle(5).into(), end_group_handle: AttHandle(5).into(), - value: build_att_data(AttAttributeDataChild::RawData([6, 7].into())), + value: [6, 7].into(), }, ] .into() @@ -261,7 +261,7 @@ mod test { data: [AttReadByGroupTypeDataElementBuilder { handle: AttHandle(3).into(), end_group_handle: AttHandle(3).into(), - value: build_att_data(AttAttributeDataChild::RawData([1].into())), + value: [1].into(), },] .into() } @@ -310,7 +310,7 @@ mod test { data: [AttReadByGroupTypeDataElementBuilder { handle: AttHandle(3).into(), end_group_handle: AttHandle(3).into(), - value: build_att_data(AttAttributeDataChild::RawData([4, 5, 6].into())) + value: [4, 5, 6].into() },] .into() } @@ -360,7 +360,7 @@ mod test { data: [AttReadByGroupTypeDataElementBuilder { handle: AttHandle(3).into(), end_group_handle: AttHandle(4).into(), - value: build_att_data(AttAttributeDataChild::RawData([4, 5].into())), + value: [4, 5].into(), },] .into() } diff --git a/system/rust/src/gatt/server/transactions/read_by_type_request.rs b/system/rust/src/gatt/server/transactions/read_by_type_request.rs index 6d663b25367..83a1b0862ac 100644 --- a/system/rust/src/gatt/server/transactions/read_by_type_request.rs +++ b/system/rust/src/gatt/server/transactions/read_by_type_request.rs @@ -2,7 +2,7 @@ use crate::{ core::uuid::Uuid, gatt::{ids::AttHandle, server::att_database::StableAttDatabase}, packets::{ - AttAttributeDataBuilder, AttChild, AttErrorCode, AttErrorResponseBuilder, AttOpcode, + AttChild, AttErrorCode, AttErrorResponseBuilder, AttOpcode, AttReadByTypeDataElementBuilder, AttReadByTypeRequestView, AttReadByTypeResponseBuilder, ParseError, }, @@ -54,7 +54,7 @@ pub async fn handle_read_by_type_request( for AttributeWithValue { attr, value } in attrs { if !out.push(AttReadByTypeDataElementBuilder { handle: attr.handle.into(), - value: AttAttributeDataBuilder { _child_: value }, + value: value.into_boxed_slice(), }) { break; } @@ -86,8 +86,8 @@ mod test { test::test_att_db::TestAttDatabase, }, }, - packets::{AttAttributeDataChild, AttReadByTypeRequestBuilder}, - utils::packet::{build_att_data, build_view_or_crash}, + packets::AttReadByTypeRequestBuilder, + utils::packet::build_view_or_crash, }; const UUID: Uuid = Uuid::new(1234); @@ -123,7 +123,7 @@ mod test { AttReadByTypeResponseBuilder { data: [AttReadByTypeDataElementBuilder { handle: AttHandle(3).into(), - value: build_att_data(AttAttributeDataChild::RawData([4, 5].into())) + value: [4, 5].into() }] .into() } @@ -180,11 +180,11 @@ mod test { data: [ AttReadByTypeDataElementBuilder { handle: AttHandle(3).into(), - value: build_att_data(AttAttributeDataChild::RawData([4, 5].into())) + value: [4, 5].into() }, AttReadByTypeDataElementBuilder { handle: AttHandle(6).into(), - value: build_att_data(AttAttributeDataChild::RawData([6, 7].into())) + value: [6, 7].into() } ] .into() @@ -232,7 +232,7 @@ mod test { AttReadByTypeResponseBuilder { data: [AttReadByTypeDataElementBuilder { handle: AttHandle(3).into(), - value: build_att_data(AttAttributeDataChild::RawData([4, 5, 6].into())) + value: [4, 5, 6].into() },] .into() } diff --git a/system/rust/src/gatt/server/transactions/read_request.rs b/system/rust/src/gatt/server/transactions/read_request.rs index fb33074c6da..ba4ea3a3fe2 100644 --- a/system/rust/src/gatt/server/transactions/read_request.rs +++ b/system/rust/src/gatt/server/transactions/read_request.rs @@ -1,8 +1,7 @@ use crate::{ gatt::server::att_database::AttDatabase, packets::{ - AttAttributeDataBuilder, AttAttributeDataChild, AttChild, AttErrorResponseBuilder, - AttOpcode, AttReadRequestView, AttReadResponseBuilder, + AttChild, AttErrorResponseBuilder, AttOpcode, AttReadRequestView, AttReadResponseBuilder, }, }; @@ -17,12 +16,7 @@ pub async fn handle_read_request( Ok(mut data) => { // as per 5.3 3F 3.4.4.4 ATT_READ_RSP, we truncate to MTU - 1 data.truncate(mtu - 1); - AttReadResponseBuilder { - value: AttAttributeDataBuilder { - _child_: AttAttributeDataChild::RawData(data.into_boxed_slice()), - }, - } - .into() + AttReadResponseBuilder { value: data.into_boxed_slice() }.into() } Err(error_code) => AttErrorResponseBuilder { opcode_in_error: AttOpcode::READ_REQUEST, @@ -46,8 +40,8 @@ mod test { test::test_att_db::TestAttDatabase, }, }, - packets::{AttAttributeDataChild, AttErrorCode, AttReadRequestBuilder, Serializable}, - utils::packet::{build_att_data, build_view_or_crash}, + packets::{AttErrorCode, AttReadRequestBuilder, Serializable}, + utils::packet::build_view_or_crash, }; fn make_db_with_handle_and_value(handle: u16, value: Vec) -> TestAttDatabase { @@ -81,9 +75,7 @@ mod test { response.to_vec().unwrap(); // check it serializes assert_eq!( response, - AttChild::AttReadResponse(AttReadResponseBuilder { - value: build_att_data(AttAttributeDataChild::RawData([4, 5].into())) - }) + AttChild::AttReadResponse(AttReadResponseBuilder { value: [4, 5].into() }) ) } diff --git a/system/rust/src/gatt/server/transactions/write_request.rs b/system/rust/src/gatt/server/transactions/write_request.rs index 23a11d9d569..b777c3fd821 100644 --- a/system/rust/src/gatt/server/transactions/write_request.rs +++ b/system/rust/src/gatt/server/transactions/write_request.rs @@ -10,7 +10,7 @@ pub async fn handle_write_request( db: &T, ) -> AttChild { let handle = request.get_handle().into(); - let value = request.get_value().get_raw_payload().collect::>(); + let value = request.get_value_iter().collect::>(); match db.write_attribute(handle, &value).await { Ok(()) => AttWriteResponseBuilder {}.into(), Err(error_code) => AttErrorResponseBuilder { @@ -39,10 +39,10 @@ mod test { }, }, packets::{ - AttAttributeDataBuilder, AttAttributeDataChild, AttChild, AttErrorCode, - AttErrorResponseBuilder, AttWriteRequestBuilder, AttWriteResponseBuilder, + AttChild, AttErrorCode, AttErrorResponseBuilder, AttWriteRequestBuilder, + AttWriteResponseBuilder, }, - utils::packet::{build_att_data, build_view_or_crash}, + utils::packet::build_view_or_crash, }; #[test] @@ -61,9 +61,7 @@ mod test { // act: write to the attribute let att_view = build_view_or_crash(AttWriteRequestBuilder { handle: AttHandle(1).into(), - value: AttAttributeDataBuilder { - _child_: AttAttributeDataChild::RawData(data.clone().into_boxed_slice()), - }, + value: data.clone().into_boxed_slice(), }); let resp = block_on(handle_write_request(att_view.view(), &db)); @@ -86,7 +84,7 @@ mod test { // act: write to the attribute let att_view = build_view_or_crash(AttWriteRequestBuilder { handle: AttHandle(1).into(), - value: build_att_data(AttAttributeDataChild::RawData([1, 2].into())), + value: [1, 2].into(), }); let resp = block_on(handle_write_request(att_view.view(), &db)); diff --git a/system/rust/src/packets.pdl b/system/rust/src/packets.pdl index c8079bec42b..77fc970322f 100644 --- a/system/rust/src/packets.pdl +++ b/system/rust/src/packets.pdl @@ -133,6 +133,10 @@ struct GattCharacteristicProperties { extended_properties: 1, } +struct AttAttributeData { + _payload_ +} + struct GattCharacteristicDeclarationValue : AttAttributeData { properties: GattCharacteristicProperties, handle: AttHandle, @@ -158,15 +162,11 @@ struct UuidAsAttData : AttAttributeData { uuid: Uuid, } -struct AttAttributeData { - _payload_ -} - packet AttFindByTypeValueRequest : Att(opcode = FIND_BY_TYPE_VALUE_REQUEST) { starting_handle : AttHandle, ending_handle : AttHandle, attribute_type : Uuid16, - attribute_value : AttAttributeData, + attribute_value : 8[], } struct AttributeHandleRange { @@ -187,7 +187,7 @@ packet AttReadByGroupTypeRequest : Att(opcode = READ_BY_GROUP_TYPE_REQUEST) { struct AttReadByGroupTypeDataElement { handle : AttHandle, end_group_handle : AttHandle, - value : AttAttributeData, + value : 8[], } packet AttReadByGroupTypeResponse : Att(opcode = READ_BY_GROUP_TYPE_RESPONSE) { @@ -203,7 +203,7 @@ packet AttReadByTypeRequest : Att(opcode = READ_BY_TYPE_REQUEST) { struct AttReadByTypeDataElement { handle : AttHandle, - value : AttAttributeData, + value : 8[], } packet AttReadByTypeResponse : Att(opcode = READ_BY_TYPE_RESPONSE) { @@ -216,12 +216,12 @@ packet AttReadRequest : Att(opcode = READ_REQUEST) { } packet AttReadResponse : Att(opcode = READ_RESPONSE) { - value: AttAttributeData, + value: 8[], } packet AttWriteRequest : Att(opcode = WRITE_REQUEST) { handle : AttHandle, - value : AttAttributeData, + value : 8[], } packet AttWriteResponse : Att(opcode = WRITE_RESPONSE) {} @@ -234,7 +234,7 @@ packet AttErrorResponse : Att(opcode = ERROR_RESPONSE) { packet AttHandleValueIndication : Att(opcode = HANDLE_VALUE_INDICATION) { handle: AttHandle, - value: AttAttributeData, + value: 8[], } packet AttHandleValueConfirmation : Att(opcode = HANDLE_VALUE_CONFIRMATION) {} @@ -249,5 +249,5 @@ packet AttExchangeMtuResponse : Att(opcode = EXCHANGE_MTU_RESPONSE) { packet AttWriteCommand : Att(opcode = WRITE_COMMAND) { handle : AttHandle, - value : AttAttributeData, + value : 8[], } diff --git a/system/rust/src/utils/packet.rs b/system/rust/src/utils/packet.rs index 790be2026be..86039636b86 100644 --- a/system/rust/src/utils/packet.rs +++ b/system/rust/src/utils/packet.rs @@ -1,8 +1,7 @@ //! Utility for packet manipulation on top of the codegen from PDL use crate::packets::{ - AttAttributeDataBuilder, AttAttributeDataChild, AttBuilder, AttChild, AttOpcode, Builder, - OwnedAttView, OwnedPacket, Serializable, + AttBuilder, AttChild, AttOpcode, Builder, OwnedAttView, OwnedPacket, Serializable, }; /// Convert an ATT builder child into an owned AttView, for use in test @@ -45,8 +44,3 @@ pub fn HACK_child_to_opcode(child: &AttChild) -> AttOpcode { AttChild::AttWriteCommand(_) => AttOpcode::WRITE_COMMAND, } } - -/// Utility to simplify assembly of AttData by reducing boilerplate -pub fn build_att_data(child: impl Into) -> AttAttributeDataBuilder { - AttAttributeDataBuilder { _child_: child.into() } -} diff --git a/system/rust/tests/gatt_server_test.rs b/system/rust/tests/gatt_server_test.rs index 2b31db764c9..9cccd51bc37 100644 --- a/system/rust/tests/gatt_server_test.rs +++ b/system/rust/tests/gatt_server_test.rs @@ -30,7 +30,7 @@ use bluetooth_core::{ }, }, packets::{ - AttAttributeDataChild, AttBuilder, AttChild, AttErrorCode, AttErrorResponseBuilder, + AttBuilder, AttChild, AttErrorCode, AttErrorResponseBuilder, AttFindByTypeValueRequestBuilder, AttFindInformationRequestBuilder, AttFindInformationResponseChild, AttHandleValueConfirmationBuilder, AttHandleValueIndicationBuilder, AttOpcode, AttReadByTypeRequestBuilder, @@ -39,7 +39,7 @@ use bluetooth_core::{ GattClientCharacteristicConfigurationBuilder, GattServiceChangedBuilder, GattServiceDeclarationValueBuilder, Packet, Serializable, UuidAsAttDataBuilder, }, - utils::packet::{build_att_data, build_att_view_or_crash}, + utils::packet::build_att_view_or_crash, }; use tokio::{ @@ -133,9 +133,10 @@ fn test_service_read() { AttBuilder { opcode: AttOpcode::READ_RESPONSE, _child_: AttReadResponseBuilder { - value: build_att_data(GattServiceDeclarationValueBuilder { - uuid: SERVICE_TYPE.into() - }) + value: GattServiceDeclarationValueBuilder { uuid: SERVICE_TYPE.into() } + .to_vec() + .unwrap() + .into(), } .into() } @@ -182,9 +183,6 @@ fn test_characteristic_read() { start_test(async move { // arrange let (mut gatt, mut transport_rx) = start_gatt_module(); - - let data = AttAttributeDataChild::RawData(DATA.into()); - let mut data_rx = create_server_and_open_connection(&mut gatt); // act @@ -214,7 +212,7 @@ fn test_characteristic_read() { resp, AttBuilder { opcode: AttOpcode::READ_RESPONSE, - _child_: AttReadResponseBuilder { value: build_att_data(data) }.into() + _child_: AttReadResponseBuilder { value: DATA.into() }.into() } ); }) @@ -225,16 +223,13 @@ fn test_characteristic_write() { start_test(async move { // arrange let (mut gatt, mut transport_rx) = start_gatt_module(); - - let data = AttAttributeDataChild::RawData(DATA.into()); - let mut data_rx = create_server_and_open_connection(&mut gatt); // act gatt.get_bearer(TCB_IDX).unwrap().handle_packet( build_att_view_or_crash(AttWriteRequestBuilder { handle: CHARACTERISTIC_HANDLE.into(), - value: build_att_data(data.clone()), + value: DATA.into(), }) .view(), ); @@ -262,7 +257,7 @@ fn test_characteristic_write() { _child_: AttWriteResponseBuilder {}.into() } ); - assert_eq!(data.to_vec().unwrap(), written_data) + assert_eq!(&DATA, written_data.as_slice()); }) } @@ -271,14 +266,11 @@ fn test_send_indication() { start_test(async move { // arrange let (mut gatt, mut transport_rx) = start_gatt_module(); - - let data = AttAttributeDataChild::RawData(DATA.into()); - create_server_and_open_connection(&mut gatt); // act let pending_indication = spawn_local( - gatt.get_bearer(TCB_IDX).unwrap().send_indication(CHARACTERISTIC_HANDLE, data.clone()), + gatt.get_bearer(TCB_IDX).unwrap().send_indication(CHARACTERISTIC_HANDLE, DATA.into()), ); let (tcb_idx, resp) = transport_rx.recv().await.unwrap(); @@ -296,7 +288,7 @@ fn test_send_indication() { opcode: AttOpcode::HANDLE_VALUE_INDICATION, _child_: AttHandleValueIndicationBuilder { handle: CHARACTERISTIC_HANDLE.into(), - value: build_att_data(data), + value: DATA.into(), } .into() } @@ -313,10 +305,11 @@ fn test_send_indication_and_disconnect() { create_server_and_open_connection(&mut gatt); // act: send an indication, then disconnect - let pending_indication = spawn_local(gatt.get_bearer(TCB_IDX).unwrap().send_indication( - CHARACTERISTIC_HANDLE, - AttAttributeDataChild::RawData([1, 2, 3, 4].into()), - )); + let pending_indication = spawn_local( + gatt.get_bearer(TCB_IDX) + .unwrap() + .send_indication(CHARACTERISTIC_HANDLE, vec![1, 2, 3, 4]), + ); transport_rx.recv().await.unwrap(); gatt.on_le_disconnect(TCB_IDX).unwrap(); @@ -333,16 +326,13 @@ fn test_write_to_descriptor() { start_test(async move { // arrange let (mut gatt, mut transport_rx) = start_gatt_module(); - - let data = AttAttributeDataChild::RawData(DATA.into()); - let mut data_rx = create_server_and_open_connection(&mut gatt); // act gatt.get_bearer(TCB_IDX).unwrap().handle_packet( build_att_view_or_crash(AttWriteRequestBuilder { handle: DESCRIPTOR_HANDLE.into(), - value: build_att_data(data.clone()), + value: DATA.into(), }) .view(), ); @@ -370,7 +360,7 @@ fn test_write_to_descriptor() { _child_: AttWriteResponseBuilder {}.into() } ); - assert_eq!(data.to_vec().unwrap(), written_data) + assert_eq!(&DATA, written_data.as_slice()); }) } @@ -505,9 +495,10 @@ fn test_service_change_indication() { starting_handle: AttHandle::MIN.into(), ending_handle: AttHandle::MAX.into(), attribute_type: PRIMARY_SERVICE_DECLARATION_UUID.try_into().unwrap(), - attribute_value: build_att_data(UuidAsAttDataBuilder { - uuid: GATT_SERVICE_UUID.into(), - }), + attribute_value: UuidAsAttDataBuilder { uuid: GATT_SERVICE_UUID.into() } + .to_vec() + .unwrap() + .into(), }) .view(), ); @@ -538,7 +529,7 @@ fn test_service_change_indication() { .into_vec() .into_iter() .find_map(|characteristic| { - let value = characteristic.value.to_vec().unwrap(); + let value = characteristic.value.to_vec(); let decl = GattCharacteristicDeclarationValueView::try_parse_from_buffer(value.as_slice()) .unwrap(); @@ -583,10 +574,13 @@ fn test_service_change_indication() { gatt.get_bearer(TCB_IDX).unwrap().handle_packet( build_att_view_or_crash(AttWriteRequestBuilder { handle: service_change_descriptor_handle, - value: build_att_data(GattClientCharacteristicConfigurationBuilder { + value: GattClientCharacteristicConfigurationBuilder { notification: 0, indication: 1, - }), + } + .to_vec() + .unwrap() + .into(), }) .view(), ); @@ -614,11 +608,12 @@ fn test_service_change_indication() { }; assert_eq!(indication.handle, service_change_char_handle.into()); assert_eq!( - indication.value, - build_att_data(GattServiceChangedBuilder { + Ok(indication.value.into()), + GattServiceChangedBuilder { start_handle: AttHandle(30).into(), end_handle: AttHandle(30).into(), - }) + } + .to_vec() ); }); } -- GitLab From 3eade2a8796f3da966798e180ead777be9f80989 Mon Sep 17 00:00:00 2001 From: Myles Watson Date: Fri, 14 Jun 2024 10:56:36 -0700 Subject: [PATCH 0021/1446] HciInterface: Allow legacy tests to use fake HCI Bug: 322230000 Test: mma -j32 Flag: TEST_ONLY Change-Id: I122c2d471324d10706fa890c4de62c0fc0d91f2d --- system/gd/hci/Android.bp | 9 ++++++++- system/gd/hci/hci_layer_fake.cc | 3 ++- system/gd/hci/hci_layer_fake.h | 6 +++--- system/test/mock/mock_main_shim_entry.cc | 3 +-- system/test/mock/mock_main_shim_entry.h | 4 ++-- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/system/gd/hci/Android.bp b/system/gd/hci/Android.bp index a6e9cb18222..9ebf5108635 100644 --- a/system/gd/hci/Android.bp +++ b/system/gd/hci/Android.bp @@ -31,10 +31,18 @@ filegroup { ], } +filegroup { + name: "BluetoothHciFake", + srcs: [ + "hci_layer_fake.cc", + ], +} + filegroup { name: "BluetoothHciUnitTestSources", srcs: [ ":BluetoothHalFake", + ":BluetoothHciFake", "acl_builder_test.cc", "acl_manager/acl_scheduler_test.cc", "acl_manager/classic_acl_connection_test.cc", @@ -49,7 +57,6 @@ filegroup { "class_of_device_unittest.cc", "controller_test.cc", "controller_unittest.cc", - "hci_layer_fake.cc", "hci_layer_test.cc", "hci_layer_unittest.cc", "hci_packets_test.cc", diff --git a/system/gd/hci/hci_layer_fake.cc b/system/gd/hci/hci_layer_fake.cc index 605ca7febdd..e431df82300 100644 --- a/system/gd/hci/hci_layer_fake.cc +++ b/system/gd/hci/hci_layer_fake.cc @@ -20,9 +20,10 @@ #include #include -#include #include +#include "packet/raw_builder.h" + namespace bluetooth { namespace hci { diff --git a/system/gd/hci/hci_layer_fake.h b/system/gd/hci/hci_layer_fake.h index 56793e4312e..645746014c1 100644 --- a/system/gd/hci/hci_layer_fake.h +++ b/system/gd/hci/hci_layer_fake.h @@ -15,13 +15,13 @@ */ #include +#include #include +#include +#include #include -#include "common/bind.h" -#include "hci/address.h" #include "hci/hci_layer.h" -#include "packet/raw_builder.h" namespace bluetooth { namespace hci { diff --git a/system/test/mock/mock_main_shim_entry.cc b/system/test/mock/mock_main_shim_entry.cc index cdd6024c024..d2cdbd5a137 100644 --- a/system/test/mock/mock_main_shim_entry.cc +++ b/system/test/mock/mock_main_shim_entry.cc @@ -18,7 +18,6 @@ #include "hci/controller_interface_mock.h" #include "hci/distance_measurement_manager_mock.h" #include "hci/hci_interface.h" -#include "hci/hci_layer_mock.h" #include "hci/le_advertising_manager_mock.h" #include "hci/le_scanning_manager_mock.h" #include "main/shim/entry.h" @@ -32,7 +31,7 @@ namespace testing { MockAclManager* mock_acl_manager_{nullptr}; MockControllerInterface* mock_controller_{nullptr}; shim::Dumpsys* shim_dumpsys_ = {}; -MockHciLayer* mock_hci_layer_{nullptr}; +HciInterface* mock_hci_layer_{nullptr}; os::Handler* mock_gd_shim_handler_{nullptr}; MockLeAdvertisingManager* mock_le_advertising_manager_{nullptr}; MockLeScanningManager* mock_le_scanning_manager_{nullptr}; diff --git a/system/test/mock/mock_main_shim_entry.h b/system/test/mock/mock_main_shim_entry.h index 394c13812f6..cde3f778f74 100644 --- a/system/test/mock/mock_main_shim_entry.h +++ b/system/test/mock/mock_main_shim_entry.h @@ -19,7 +19,7 @@ #include "hci/acl_manager_mock.h" #include "hci/controller_interface_mock.h" #include "hci/distance_measurement_manager_mock.h" -#include "hci/hci_layer_mock.h" +#include "hci/hci_interface.h" #include "hci/le_advertising_manager_mock.h" #include "hci/le_scanning_manager_mock.h" #include "shim/dumpsys.h" @@ -31,7 +31,7 @@ namespace testing { extern MockAclManager* mock_acl_manager_; extern MockControllerInterface* mock_controller_; extern std::function shim_dumpsys_; -extern MockHciLayer* mock_hci_layer_; +extern HciInterface* mock_hci_layer_; extern os::Handler* mock_gd_shim_handler_; extern MockLeAdvertisingManager* mock_le_advertising_manager_; extern MockLeScanningManager* mock_le_scanning_manager_; -- GitLab From f3dbac566a602d6baf4bd0b2ff0df965a0d7def7 Mon Sep 17 00:00:00 2001 From: Myles Watson Date: Fri, 14 Jun 2024 13:11:50 -0700 Subject: [PATCH 0022/1446] BtmInquiry: Add a test framework for results Bug: 343302576 Test: atest net_test_stack_btm Flag: TEST_ONLY Change-Id: I6115046529e38ca43eaf08e5da448185e6cf055f --- system/stack/Android.bp | 1 + system/stack/test/btm/stack_btm_inq_test.cc | 138 +++++++++++++++++++- 2 files changed, 137 insertions(+), 2 deletions(-) diff --git a/system/stack/Android.bp b/system/stack/Android.bp index 0ba6c89a915..567d4211462 100644 --- a/system/stack/Android.bp +++ b/system/stack/Android.bp @@ -1564,6 +1564,7 @@ cc_test { srcs: [ ":BluetoothHalSources_hci_host", ":BluetoothHalSources_ranging_host", + ":BluetoothHciFake", ":BluetoothOsSources_host", ":OsiCompatSources", ":TestCommonMainHandler", diff --git a/system/stack/test/btm/stack_btm_inq_test.cc b/system/stack/test/btm/stack_btm_inq_test.cc index 0301bf49327..5192773858e 100644 --- a/system/stack/test/btm/stack_btm_inq_test.cc +++ b/system/stack/test/btm/stack_btm_inq_test.cc @@ -14,22 +14,62 @@ * limitations under the License. */ -#include +#include +#include #include #include -#include "hci_error_code.h" +#include + +#include "common/contextual_callback.h" +#include "hci/address.h" +#include "hci/class_of_device.h" +#include "hci/hci_layer_fake.h" +#include "hci/hci_packets.h" #include "stack/btm/btm_int_types.h" +#include "stack/include/btm_api.h" +#include "stack/include/hci_error_code.h" #include "stack/include/inq_hci_link_interface.h" +#include "stack/include/main_thread.h" #include "stack/test/btm/btm_test_fixtures.h" #include "test/fake/fake_looper.h" +#include "test/mock/mock_main_shim_entry.h" #include "test/mock/mock_osi_allocator.h" #include "test/mock/mock_osi_thread.h" #include "types/raw_address.h" extern tBTM_CB btm_cb; +using bluetooth::common::ContextualCallback; +using bluetooth::common::ContextualOnceCallback; +using bluetooth::hci::Address; +using bluetooth::hci::CommandCompleteView; +using bluetooth::hci::CommandStatusView; +using bluetooth::hci::EventView; +using bluetooth::hci::ExtendedInquiryResultBuilder; +using bluetooth::hci::ExtendedInquiryResultView; +using bluetooth::hci::InquiryResponse; +using bluetooth::hci::InquiryResultBuilder; +using bluetooth::hci::InquiryResultView; +using bluetooth::hci::InquiryResultWithRssiBuilder; +using bluetooth::hci::InquiryResultWithRssiView; +using bluetooth::hci::InquiryStatusBuilder; +using bluetooth::hci::InquiryView; +using bluetooth::hci::OpCode; +using bluetooth::hci::EventCode::EXTENDED_INQUIRY_RESULT; +using bluetooth::hci::EventCode::INQUIRY_COMPLETE; +using bluetooth::hci::EventCode::INQUIRY_RESULT; +using bluetooth::hci::EventCode::INQUIRY_RESULT_WITH_RSSI; +using testing::_; +using testing::A; +using testing::Matcher; +using testing::NiceMock; +using testing::Return; +using testing::SaveArg; + namespace { +const Address kAddress = Address({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); +const Address kAddress2 = Address({0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc}); const RawAddress kRawAddress = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); const RawAddress kRawAddress2 = RawAddress({0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc}); @@ -39,6 +79,8 @@ const BD_NAME kEmptyName = ""; tBTM_REMOTE_DEV_NAME gBTM_REMOTE_DEV_NAME{}; bool gBTM_REMOTE_DEV_NAME_sent{false}; +static constexpr uint8_t kNumCommandPackets = 1; + } // namespace class BtmInqTest : public BtmWithMocksTest { @@ -142,3 +184,95 @@ TEST_F(BtmInqActiveTest, btm_process_remote_name__different_address) { ASSERT_FALSE(gBTM_REMOTE_DEV_NAME_sent); } + +class BtmInquiryCallbacks { + public: + virtual ~BtmInquiryCallbacks() = default; + virtual void btm_inq_results_cb(tBTM_INQ_RESULTS*, const uint8_t*, + uint16_t) = 0; + virtual void btm_inq_cmpl_cb(void*) = 0; +}; + +class MockBtmInquiryCallbacks : public BtmInquiryCallbacks { + public: + MOCK_METHOD(void, btm_inq_results_cb, + (tBTM_INQ_RESULTS * p_inq_results, const uint8_t* p_eir, + uint16_t eir_len), + (override)); + MOCK_METHOD(void, btm_inq_cmpl_cb, (void*), (override)); +}; + +MockBtmInquiryCallbacks* inquiry_callback_ptr = nullptr; + +void btm_inq_results_cb(tBTM_INQ_RESULTS* p_inq_results, const uint8_t* p_eir, + uint16_t eir_len) { + inquiry_callback_ptr->btm_inq_results_cb(p_inq_results, p_eir, eir_len); +} + +void btm_inq_cmpl_cb(void* p1) { inquiry_callback_ptr->btm_inq_cmpl_cb(p1); } + +class BtmDeviceInquiryTest : public BtmInqTest { + protected: + void SetUp() override { + BtmInqTest::SetUp(); + main_thread_start_up(); + inquiry_callback_ptr = &callbacks_; + bluetooth::hci::testing::mock_controller_ = &controller_; + ON_CALL(controller_, SupportsBle()).WillByDefault(Return(true)); + bluetooth::hci::testing::mock_hci_layer_ = &hci_layer_; + + // Start Inquiry + EXPECT_EQ(BTM_CMD_STARTED, + BTM_StartInquiry(btm_inq_results_cb, btm_inq_cmpl_cb)); + auto view = hci_layer_.GetCommand(OpCode::INQUIRY); + hci_layer_.IncomingEvent(InquiryStatusBuilder::Create( + bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets)); + + // Send one response to synchronize + std::promise first_result_promise; + auto first_result = first_result_promise.get_future(); + EXPECT_CALL(*inquiry_callback_ptr, btm_inq_results_cb(_, _, _)) + .WillOnce( + [&first_result_promise]() { first_result_promise.set_value(); }) + .RetiresOnSaturation(); + + InquiryResponse one_device(kAddress, + bluetooth::hci::PageScanRepetitionMode::R0, + bluetooth::hci::ClassOfDevice(), 0x1234); + hci_layer_.IncomingEvent(InquiryResultBuilder::Create({one_device})); + + EXPECT_EQ(std::future_status::ready, + first_result.wait_for(std::chrono::seconds(1))); + } + + void TearDown() override { + BTM_CancelInquiry(); + inquiry_callback_ptr = nullptr; + main_thread_shut_down(); + BtmInqTest::TearDown(); + } + + NiceMock controller_; + bluetooth::hci::HciLayerFake hci_layer_; + ContextualCallback on_exteneded_inq_result_; + ContextualCallback on_inq_complete_; + ContextualCallback on_inq_result_; + ContextualCallback on_inq_result_with_rssi_; + MockBtmInquiryCallbacks callbacks_; +}; + +TEST_F(BtmDeviceInquiryTest, bta_dm_disc_device_discovery_single_result) { + std::promise one_result_promise; + auto one_result = one_result_promise.get_future(); + EXPECT_CALL(*inquiry_callback_ptr, btm_inq_results_cb(_, _, _)) + .WillOnce([&one_result_promise]() { one_result_promise.set_value(); }) + .RetiresOnSaturation(); + + InquiryResponse one_device(kAddress2, + bluetooth::hci::PageScanRepetitionMode::R0, + bluetooth::hci::ClassOfDevice(), 0x2345); + hci_layer_.IncomingEvent(InquiryResultBuilder::Create({one_device})); + + EXPECT_EQ(std::future_status::ready, + one_result.wait_for(std::chrono::seconds(1))); +} -- GitLab From ef9163e3e9b7b3a3519ec00978ec2af20f169824 Mon Sep 17 00:00:00 2001 From: Charlie Boutier Date: Fri, 14 Jun 2024 19:09:54 +0000 Subject: [PATCH 0023/1446] BumbleBluetoothTests: order the Rules Test: atest BumbleBluetoothTests Bug: 319885398 Flag: TEST_ONLY Change-Id: Id1bc645cbe29ef15218681e1bb17c36f67967fd0 --- .../bumble/src/android/bluetooth/GattClientTest.java | 10 ++++++---- .../bluetooth/GattServerConnectWithoutScanTest.java | 8 +++++--- .../src/android/bluetooth/LeLegacyAdvertisingTest.java | 5 +++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/framework/tests/bumble/src/android/bluetooth/GattClientTest.java b/framework/tests/bumble/src/android/bluetooth/GattClientTest.java index a32de36102f..0f8e372259c 100644 --- a/framework/tests/bumble/src/android/bluetooth/GattClientTest.java +++ b/framework/tests/bumble/src/android/bluetooth/GattClientTest.java @@ -46,7 +46,6 @@ import com.google.testing.junit.testparameterinjector.TestParameter; import com.google.testing.junit.testparameterinjector.TestParameterInjector; import org.junit.Assume; -import org.junit.ClassRule; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; @@ -85,11 +84,14 @@ public class GattClientTest { UUID.fromString("00000000-0000-0000-0000-00000000000"); private static final UUID TEST_CHARACTERISTIC_UUID = UUID.fromString("00010001-0000-0000-0000-000000000000"); - @ClassRule public static final AdoptShellPermissionsRule PERM = new AdoptShellPermissionsRule(); - @Rule public final PandoraDevice mBumble = new PandoraDevice(); + @Rule(order = 2) + public final AdoptShellPermissionsRule mPermissionRule = new AdoptShellPermissionsRule(); - @Rule + @Rule(order = 1) + public final PandoraDevice mBumble = new PandoraDevice(); + + @Rule(order = 0) public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); private final Context mContext = ApplicationProvider.getApplicationContext(); diff --git a/framework/tests/bumble/src/android/bluetooth/GattServerConnectWithoutScanTest.java b/framework/tests/bumble/src/android/bluetooth/GattServerConnectWithoutScanTest.java index 578a77817ae..f87d1bdd2e1 100644 --- a/framework/tests/bumble/src/android/bluetooth/GattServerConnectWithoutScanTest.java +++ b/framework/tests/bumble/src/android/bluetooth/GattServerConnectWithoutScanTest.java @@ -50,11 +50,13 @@ public class GattServerConnectWithoutScanTest { private static final String TAG = "GattServerConnectWithoutScanTest"; private static final int TIMEOUT_GATT_CONNECTION_MS = 2_000; - @Rule public final AdoptShellPermissionsRule mPermissionRule = new AdoptShellPermissionsRule(); + @Rule(order = 2) + public final AdoptShellPermissionsRule mPermissionRule = new AdoptShellPermissionsRule(); - @Rule public final PandoraDevice mBumble = new PandoraDevice(); + @Rule(order = 1) + public final PandoraDevice mBumble = new PandoraDevice(); - @Rule + @Rule(order = 0) public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); private final Context mContext = ApplicationProvider.getApplicationContext(); diff --git a/framework/tests/bumble/src/android/bluetooth/LeLegacyAdvertisingTest.java b/framework/tests/bumble/src/android/bluetooth/LeLegacyAdvertisingTest.java index d56ec087e2d..49278712802 100644 --- a/framework/tests/bumble/src/android/bluetooth/LeLegacyAdvertisingTest.java +++ b/framework/tests/bumble/src/android/bluetooth/LeLegacyAdvertisingTest.java @@ -45,9 +45,10 @@ import java.util.concurrent.TimeUnit; public class LeLegacyAdvertisingTest { private static final int TIMEOUT_MS = 1_000; - @Rule public final AdoptShellPermissionsRule mPermissionRule = new AdoptShellPermissionsRule(); + @Rule(order = 1) + public final AdoptShellPermissionsRule mPermissionRule = new AdoptShellPermissionsRule(); - @Rule + @Rule(order = 0) public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); @RequiresFlagsEnabled(Flags.FLAG_BLE_CHECK_DATA_LENGTH_ON_LEGACY_ADVERTISING) -- GitLab From 1bea83c1fff7e30482da502d7b3d2ac8ce7ad087 Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Wed, 12 Jun 2024 01:39:59 +0000 Subject: [PATCH 0024/1446] Add expresslog metrics for a2dp codec usage This is pending the addition of a more exhaustive atom tracking more information about a2dp audio sessions in general. Bug: 346590002 Test: m com.android.btservices Flag: EXEMPT, metric change Change-Id: Ia671c9596698932ac5604f1a75d3bfce3bca7f31 --- android/app/Android.bp | 3 ++ system/audio_hal_interface/fuzzer/Android.bp | 3 ++ system/gd/Android.bp | 6 ++++ system/gd/os/android/metrics.cc | 32 ++++++++++++++++++-- system/stack/Android.bp | 3 ++ system/stack/test/fuzzers/Android.bp | 3 ++ system/test/headless/Android.bp | 3 ++ system/test/suite/Android.bp | 3 ++ 8 files changed, 54 insertions(+), 2 deletions(-) diff --git a/android/app/Android.bp b/android/app/Android.bp index ec7292cb856..a4d83579918 100644 --- a/android/app/Android.bp +++ b/android/app/Android.bp @@ -134,6 +134,7 @@ cc_library_shared { "libchrome", "libcutils", "libevent", + "libexpresslog", "libflatbuffers-cpp", "libfmq", "libg722codec", @@ -144,6 +145,8 @@ cc_library_shared { "libosi", "libprotobuf-cpp-lite", "libstatslog_bt", + "libstatslog_express", + "libtextclassifier_hash_static", "libudrv-uipc", "libutils", "server_configurable_flags", diff --git a/system/audio_hal_interface/fuzzer/Android.bp b/system/audio_hal_interface/fuzzer/Android.bp index 15df156d2c5..05ef5cb6542 100644 --- a/system/audio_hal_interface/fuzzer/Android.bp +++ b/system/audio_hal_interface/fuzzer/Android.bp @@ -90,6 +90,7 @@ cc_defaults { "libchrome", "libcutils", "libevent", + "libexpresslog", "libg722codec", "libhidlbase", "libjsoncpp", @@ -99,6 +100,8 @@ cc_defaults { "libosi", "libprotobuf-cpp-lite", "libstatslog_bt", + "libstatslog_express", + "libtextclassifier_hash_static", "libudrv-uipc", "libutils", "libvndksupport", diff --git a/system/gd/Android.bp b/system/gd/Android.bp index 3c876a05d6b..ec7ebd51ca5 100644 --- a/system/gd/Android.bp +++ b/system/gd/Android.bp @@ -125,8 +125,14 @@ cc_defaults { "libcutils", "libhidlbase", "libstatslog_bt", + "libstatssocket", "libutils", ], + static_libs: [ + "libexpresslog", + "libstatslog_express", + "libtextclassifier_hash_static", + ], whole_static_libs: [ "android.hardware.bluetooth-V1-ndk", "android.hardware.bluetooth.ranging-V1-ndk", diff --git a/system/gd/os/android/metrics.cc b/system/gd/os/android/metrics.cc index 45b7d9ac5b4..0223b42df9c 100644 --- a/system/gd/os/android/metrics.cc +++ b/system/gd/os/android/metrics.cc @@ -20,12 +20,14 @@ #include "os/metrics.h" +#include #include #include #include "common/audit_log.h" #include "common/metric_id_manager.h" #include "common/strings.h" +#include "hardware/bt_av.h" #include "hci/hci_packets.h" #include "metrics/metrics_state.h" #include "os/log.h" @@ -206,8 +208,34 @@ void LogMetricA2dpSessionMetricsEvent( int /* buffer_overruns_total */, float /* buffer_underruns_average */, int /* buffer_underruns_count */, - int64_t /* codec_index */, - bool /* is_a2dp_offload */) {} + int64_t codec_index, + bool /* is_a2dp_offload */) { + char const* metric_id = nullptr; + switch (codec_index) { + case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC: + metric_id = "bluetooth.value_sbc_codec_usage_over_a2dp"; + break; + case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC: + metric_id = "bluetooth.value_aac_codec_usage_over_a2dp"; + break; + case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX: + metric_id = "bluetooth.value_aptx_codec_usage_over_a2dp"; + break; + case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD: + metric_id = "bluetooth.value_aptx_hd_codec_usage_over_a2dp"; + break; + case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC: + metric_id = "bluetooth.value_ldac_codec_usage_over_a2dp"; + break; + case BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS: + metric_id = "bluetooth.value_opus_codec_usage_over_a2dp"; + break; + default: + return; + } + + android::expresslog::Counter::logIncrement(metric_id); +} void LogMetricHfpPacketLossStats( const Address& /* address */, diff --git a/system/stack/Android.bp b/system/stack/Android.bp index fcdd01a3564..07e5119660a 100644 --- a/system/stack/Android.bp +++ b/system/stack/Android.bp @@ -772,6 +772,9 @@ cc_test { static_libs: [ "android.hardware.bluetooth@1.0", "android.hardware.bluetooth@1.1", + "libexpresslog", + "libstatslog_express", + "libtextclassifier_hash_static", ], }, host: { diff --git a/system/stack/test/fuzzers/Android.bp b/system/stack/test/fuzzers/Android.bp index 66e8ee08c7b..c90c68493a2 100644 --- a/system/stack/test/fuzzers/Android.bp +++ b/system/stack/test/fuzzers/Android.bp @@ -60,11 +60,14 @@ cc_defaults { "libbte", "libbtif", "libbtif-core", + "libexpresslog", "libg722codec", "liblc3", "libopus", "libosi", "libstatslog_bt", + "libstatslog_express", + "libtextclassifier_hash_static", "libudrv-uipc", ], shared_libs: [ diff --git a/system/test/headless/Android.bp b/system/test/headless/Android.bp index 1f6e0b4c267..3c0744d25ab 100644 --- a/system/test/headless/Android.bp +++ b/system/test/headless/Android.bp @@ -146,6 +146,9 @@ cc_binary { "android.hardware.bluetooth@1.0", "android.hardware.bluetooth@1.1", "android.system.suspend.control-V1-ndk", + "libexpresslog", + "libstatslog_express", + "libtextclassifier_hash_static", ], shared_libs: [ "android.system.suspend-V1-ndk", diff --git a/system/test/suite/Android.bp b/system/test/suite/Android.bp index 505d7ab089b..ba6b25a37a2 100644 --- a/system/test/suite/Android.bp +++ b/system/test/suite/Android.bp @@ -90,6 +90,7 @@ cc_defaults { "libbtif-core", "libc++fs", "libcom.android.sysprop.bluetooth.wrapped", + "libexpresslog", "libflatbuffers-cpp", "libg722codec", "libgmock", @@ -97,6 +98,8 @@ cc_defaults { "libopus", "libosi", "libstatslog_bt", + "libstatslog_express", + "libtextclassifier_hash_static", ], header_libs: [ "libbluetooth_headers", -- GitLab From cad927034a371b82a4a07a16ec442eb261f6153f Mon Sep 17 00:00:00 2001 From: Brian Delwiche Date: Thu, 16 May 2024 20:47:44 +0000 Subject: [PATCH 0025/1446] Fix OOB write in build_read_multi_rsp of gatt_sr.cc build_read_multi_rsp is missing a bounds check, which can lead to an OOB write when the mtu parameter is set to zero. Add that bounds check. Bug: 323850943 Test: atest GattSrTest Test: researcher POC Tag: #security Flag: EXEMPT trivial validity checks Ignore-AOSP-First: Security Change-Id: I18e4325dbc9d6814220332288c85b114d0415c2f --- system/stack/eatt/eatt.h | 1 + system/stack/gatt/gatt_sr.cc | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/system/stack/eatt/eatt.h b/system/stack/eatt/eatt.h index 62bf2482066..0a1a591a54e 100644 --- a/system/stack/eatt/eatt.h +++ b/system/stack/eatt/eatt.h @@ -100,6 +100,7 @@ class EattChannel { void EattChannelSetTxMTU(uint16_t tx_mtu) { this->tx_mtu_ = std::min(tx_mtu, EATT_MAX_TX_MTU); + this->tx_mtu_ = std::max(tx_mtu, EATT_MIN_MTU_MPS); } }; diff --git a/system/stack/gatt/gatt_sr.cc b/system/stack/gatt/gatt_sr.cc index 9c40fedb7d6..1785372507b 100644 --- a/system/stack/gatt/gatt_sr.cc +++ b/system/stack/gatt/gatt_sr.cc @@ -162,6 +162,13 @@ static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) { uint8_t* p; bool is_overflow = false; + // We need at least one extra byte for the opcode + if (mtu == 0) { + log::error("Invalid MTU"); + p_cmd->status = GATT_ILLEGAL_PARAMETER; + return; + } + len = sizeof(BT_HDR) + L2CAP_MIN_OFFSET + mtu; BT_HDR* p_buf = (BT_HDR*)osi_calloc(len); p_buf->offset = L2CAP_MIN_OFFSET; -- GitLab From 803cfcf18b11de47ae49f1ec45466f3eec64ec84 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Mon, 10 Jun 2024 09:38:13 +0200 Subject: [PATCH 0026/1446] CoreInterface::onLinkDown transport Classic profiles don't care about LE transport connection/disconnection Test: switch between LE Audio and Classic multiple times Test: mma -j32 Flag: exempt, trivial Bug: 334762961 Change-Id: I75aad0d401f836347afc75d58f68fa93339e04ac --- system/btif/include/core_callbacks.h | 3 ++- system/btif/include/mock_core_callbacks.h | 3 ++- system/btif/src/bluetooth.cc | 4 +++- system/btif/src/btif_dm.cc | 3 ++- system/test/common/core_interface.cc | 3 ++- system/test/common/core_interface.h | 2 +- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/system/btif/include/core_callbacks.h b/system/btif/include/core_callbacks.h index 5dab0f52631..7d9f0e1cb7b 100644 --- a/system/btif/include/core_callbacks.h +++ b/system/btif/include/core_callbacks.h @@ -146,7 +146,8 @@ struct CoreInterface { virtual bt_status_t toggleProfile(tBTA_SERVICE_ID service_id, bool enable) = 0; virtual void removeDeviceFromProfiles(const RawAddress& bd_addr) = 0; - virtual void onLinkDown(const RawAddress& bd_addr) = 0; + virtual void onLinkDown(const RawAddress& bd_addr, + tBT_TRANSPORT transport) = 0; CoreInterface(EventCallbacks* eventCallbacks, ConfigInterface* configInterface, CodecInterface* msbcCodec, diff --git a/system/btif/include/mock_core_callbacks.h b/system/btif/include/mock_core_callbacks.h index 900bf5aa1a4..c5ea2365b1a 100644 --- a/system/btif/include/mock_core_callbacks.h +++ b/system/btif/include/mock_core_callbacks.h @@ -126,7 +126,8 @@ struct MockCoreInterface : public CoreInterface { (tBTA_SERVICE_ID service_id, bool enable), ()); MOCK_METHOD((void), removeDeviceFromProfiles, (const RawAddress& bd_addr), ()); - MOCK_METHOD((void), onLinkDown, (const RawAddress& bd_addr), ()); + MOCK_METHOD((void), onLinkDown, + (const RawAddress& bd_addr, tBT_TRANSPORT transport), ()); }; } // namespace testing diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc index 0a1c48d3040..319d65e99ca 100644 --- a/system/btif/src/bluetooth.cc +++ b/system/btif/src/bluetooth.cc @@ -331,7 +331,9 @@ struct CoreInterfaceImpl : bluetooth::core::CoreInterface { } } - void onLinkDown(const RawAddress& bd_addr) override { + void onLinkDown(const RawAddress& bd_addr, tBT_TRANSPORT transport) override { + if (transport != BT_TRANSPORT_BR_EDR) return; + if (com::android::bluetooth::flags::a2dp_concurrent_source_sink()) { btif_av_acl_disconnected(bd_addr, A2dpType::kSource); btif_av_acl_disconnected(bd_addr, A2dpType::kSink); diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index 8574121bb6b..0b46b2115ca 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -2464,7 +2464,8 @@ void btif_dm_acl_evt(tBTA_DM_ACL_EVT event, tBTA_DM_ACL* p_data) { case BTA_DM_LINK_DOWN_EVT: { bd_addr = p_data->link_down.bd_addr; btm_set_bond_type_dev(p_data->link_down.bd_addr, BOND_TYPE_UNKNOWN); - GetInterfaceToProfiles()->onLinkDown(bd_addr); + GetInterfaceToProfiles()->onLinkDown( + bd_addr, p_data->link_down.transport_link_type); bt_conn_direction_t direction; switch (btm_get_acl_disc_reason_code()) { diff --git a/system/test/common/core_interface.cc b/system/test/common/core_interface.cc index e6da45c4dc3..244289c5a1c 100644 --- a/system/test/common/core_interface.cc +++ b/system/test/common/core_interface.cc @@ -126,4 +126,5 @@ bt_status_t MockCoreInterface::toggleProfile(tBTA_SERVICE_ID /* service_id */, void MockCoreInterface::removeDeviceFromProfiles( const RawAddress& /* bd_addr */){}; -void MockCoreInterface::onLinkDown(const RawAddress& /* bd_addr */){}; +void MockCoreInterface::onLinkDown(const RawAddress& /* bd_addr */, + tBT_TRANSPORT /* transport */){}; diff --git a/system/test/common/core_interface.h b/system/test/common/core_interface.h index 96e38cad89a..4dad69d6f8b 100644 --- a/system/test/common/core_interface.h +++ b/system/test/common/core_interface.h @@ -27,5 +27,5 @@ struct MockCoreInterface : bluetooth::core::CoreInterface { void onBluetoothEnabled() override; bt_status_t toggleProfile(tBTA_SERVICE_ID service_id, bool enable) override; void removeDeviceFromProfiles(const RawAddress& bd_addr) override; - void onLinkDown(const RawAddress& bd_addr) override; + void onLinkDown(const RawAddress& bd_addr, tBT_TRANSPORT transport) override; }; -- GitLab From 1b301f4350f3ec88d5214a33887af7ace71678bf Mon Sep 17 00:00:00 2001 From: Hsin-chen Chuang Date: Mon, 17 Jun 2024 01:31:34 +0800 Subject: [PATCH 0027/1446] floss: Run `cargo clippy --fix` Bug: 343315863 Tag: #floss Test: mmm packages/modules/Bluetooth Test: ./build.py --target test Test: Deploy to Cherry, tested PhoneHub/SmartLock/FastPair/NearbyShare Test: bluetooth_AdapterQuickHealth.AVL.all_floss Flag: EXEMPT, Floss-only changes Change-Id: Id1c5edc76fbe946d9d0f1b89b5fad21e44ffb583 --- system/gd/rust/linux/client/src/callbacks.rs | 24 +-- .../rust/linux/client/src/command_handler.rs | 71 ++++---- system/gd/rust/linux/client/src/dbus_iface.rs | 10 +- system/gd/rust/linux/client/src/editor.rs | 12 +- system/gd/rust/linux/client/src/main.rs | 18 +- .../rust/linux/mgmt/src/bluetooth_manager.rs | 12 +- system/gd/rust/linux/mgmt/src/config_util.rs | 35 ++-- system/gd/rust/linux/mgmt/src/main.rs | 2 +- system/gd/rust/linux/mgmt/src/migrate.rs | 44 +++-- .../linux/mgmt/src/powerd_suspend_manager.rs | 4 +- .../gd/rust/linux/mgmt/src/service_watcher.rs | 4 +- .../gd/rust/linux/mgmt/src/state_machine.rs | 104 ++++++------ system/gd/rust/linux/service/build.rs | 2 +- .../rust/linux/service/src/iface_bluetooth.rs | 11 +- .../linux/service/src/iface_bluetooth_gatt.rs | 6 +- .../service/src/iface_bluetooth_media.rs | 2 +- .../linux/service/src/interface_manager.rs | 2 +- system/gd/rust/linux/service/src/main.rs | 2 +- .../rust/linux/stack/src/battery_manager.rs | 3 +- .../stack/src/battery_provider_manager.rs | 3 +- .../rust/linux/stack/src/battery_service.rs | 17 +- system/gd/rust/linux/stack/src/bluetooth.rs | 81 +++++---- .../rust/linux/stack/src/bluetooth_admin.rs | 3 +- .../gd/rust/linux/stack/src/bluetooth_adv.rs | 144 ++++++++-------- .../gd/rust/linux/stack/src/bluetooth_gatt.rs | 159 +++++++----------- .../rust/linux/stack/src/bluetooth_media.rs | 144 ++++++++-------- system/gd/rust/linux/stack/src/dis.rs | 4 +- .../gd/rust/linux/stack/src/socket_manager.rs | 41 ++--- system/gd/rust/linux/stack/src/suspend.rs | 2 +- system/gd/rust/linux/stack/src/uuid.rs | 4 +- .../rust/linux/utils/src/at_command_parser.rs | 24 +-- system/gd/rust/linux/utils/src/cod.rs | 12 +- system/gd/rust/linux/utils/src/socket.rs | 16 +- system/gd/rust/linux/utils/src/uhid.rs | 3 +- system/gd/rust/linux/utils/src/uinput.rs | 21 ++- system/gd/rust/topshim/build.rs | 4 +- system/gd/rust/topshim/tests/bdaddr.rs | 8 +- 37 files changed, 493 insertions(+), 565 deletions(-) diff --git a/system/gd/rust/linux/client/src/callbacks.rs b/system/gd/rust/linux/client/src/callbacks.rs index c2296aefdb9..707e72d16c9 100644 --- a/system/gd/rust/linux/client/src/callbacks.rs +++ b/system/gd/rust/linux/client/src/callbacks.rs @@ -285,7 +285,7 @@ impl IBluetoothCallback for BtCallback { BtBondState::Bonding => (), } - let device = BluetoothDevice { address: address, name: String::from("Classic device") }; + let device = BluetoothDevice { address, name: String::from("Classic device") }; // If bonded, we should also automatically connect all enabled profiles if BtBondState::Bonded == state.into() { @@ -426,25 +426,25 @@ impl IScannerCallback for ScannerCallback { } fn on_scan_result(&mut self, scan_result: ScanResult) { - if self.context.lock().unwrap().active_scanner_ids.len() > 0 { + if !self.context.lock().unwrap().active_scanner_ids.is_empty() { print_info!("Scan result: {:#?}", scan_result); } } fn on_advertisement_found(&mut self, scanner_id: u8, scan_result: ScanResult) { - if self.context.lock().unwrap().active_scanner_ids.len() > 0 { + if !self.context.lock().unwrap().active_scanner_ids.is_empty() { print_info!("Advertisement found for scanner_id {} : {:#?}", scanner_id, scan_result); } } fn on_advertisement_lost(&mut self, scanner_id: u8, scan_result: ScanResult) { - if self.context.lock().unwrap().active_scanner_ids.len() > 0 { + if !self.context.lock().unwrap().active_scanner_ids.is_empty() { print_info!("Advertisement lost for scanner_id {} : {:#?}", scanner_id, scan_result); } } fn on_suspend_mode_change(&mut self, suspend_mode: SuspendMode) { - if self.context.lock().unwrap().active_scanner_ids.len() > 0 { + if !self.context.lock().unwrap().active_scanner_ids.is_empty() { print_info!("Scan suspend mode change: {:#?}", suspend_mode); } } @@ -951,7 +951,7 @@ impl IBluetoothGattServerCallback for BtGattServerCallback { return; } self.context.lock().unwrap().pending_gatt_request = - Some(GattRequest { address: addr, id: trans_id, offset: offset, value: vec![] }); + Some(GattRequest { address: addr, id: trans_id, offset, value: vec![] }); } fn on_descriptor_read_request( @@ -978,7 +978,7 @@ impl IBluetoothGattServerCallback for BtGattServerCallback { return; } self.context.lock().unwrap().pending_gatt_request = - Some(GattRequest { address: addr, id: trans_id, offset: offset, value: vec![] }); + Some(GattRequest { address: addr, id: trans_id, offset, value: vec![] }); } fn on_characteristic_write_request( @@ -1012,7 +1012,7 @@ impl IBluetoothGattServerCallback for BtGattServerCallback { return; } self.context.lock().unwrap().pending_gatt_request = - Some(GattRequest { address: addr, id: trans_id, offset: offset, value: value }); + Some(GattRequest { address: addr, id: trans_id, offset, value }); } fn on_descriptor_write_request( @@ -1046,7 +1046,7 @@ impl IBluetoothGattServerCallback for BtGattServerCallback { return; } self.context.lock().unwrap().pending_gatt_request = - Some(GattRequest { address: addr, id: trans_id, offset: offset, value: value }); + Some(GattRequest { address: addr, id: trans_id, offset, value }); } fn on_execute_write(&mut self, addr: RawAddress, trans_id: i32, exec_write: bool) { @@ -1241,7 +1241,7 @@ impl IBluetoothSocketManagerCallbacks for BtSocketManagerCallback { socket.uuid, ); - let callback_id = self.context.lock().unwrap().socket_manager_callback_id.clone().unwrap(); + let callback_id = self.context.lock().unwrap().socket_manager_callback_id.unwrap(); self.context.lock().unwrap().run_callback(Box::new(move |context| { let status = context.lock().unwrap().socket_manager_dbus.as_mut().unwrap().accept( @@ -1434,7 +1434,7 @@ impl MediaCallback { fn timestamp_to_string(ts_in_us: u64) -> String { i64::try_from(ts_in_us) - .and_then(|ts| Ok(Utc.timestamp_nanos(ts * 1000).to_rfc3339())) + .map(|ts| Utc.timestamp_nanos(ts * 1000).to_rfc3339()) .unwrap_or("UNKNOWN".to_string()) } @@ -1625,7 +1625,7 @@ impl IBatteryManagerCallback for BatteryManagerCallback { fn on_battery_info_updated(&mut self, remote_address: RawAddress, battery_set: BatterySet) { let address = remote_address.to_string(); if self.context.lock().unwrap().battery_address_filter.contains(&address) { - if battery_set.batteries.len() == 0 { + if battery_set.batteries.is_empty() { print_info!( "Battery info for address '{}' updated with empty battery set. \ The batteries for this device may have been removed.", diff --git a/system/gd/rust/linux/client/src/command_handler.rs b/system/gd/rust/linux/client/src/command_handler.rs index e586eb51935..cdc4a3f3ae5 100644 --- a/system/gd/rust/linux/client/src/command_handler.rs +++ b/system/gd/rust/linux/client/src/command_handler.rs @@ -101,9 +101,9 @@ struct DisplayList(Vec); impl Display for DisplayList { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let _ = write!(f, "[\n"); + let _ = writeln!(f, "["); for item in self.0.iter() { - let _ = write!(f, " {}\n", item); + let _ = writeln!(f, " {}", item); } write!(f, "]") @@ -429,7 +429,7 @@ impl CommandHandler { _ => match self.command_options.get(command) { Some(cmd) => { let rules = cmd.rules.clone(); - match (cmd.function_pointer)(self, &args) { + match (cmd.function_pointer)(self, args) { Ok(()) => true, Err(CommandError::InvalidArgs) => { print_error!("Invalid arguments. Usage:\n{}", rules.join("\n")); @@ -443,7 +443,7 @@ impl CommandHandler { } None => { println!("'{}' is an invalid command!", command); - self.cmd_help(&args).ok(); + self.cmd_help(args).ok(); false } }, @@ -464,7 +464,7 @@ impl CommandHandler { } fn cmd_help(&mut self, args: &Vec) -> CommandResult { - if let Some(command) = args.get(0) { + if let Some(command) = args.first() { match self.command_options.get(command) { Some(cmd) => { println!( @@ -501,7 +501,7 @@ impl CommandHandler { for (key, val) in self.command_options.iter() { println!( "{}\n{}\n{}", - wrap_help_text(&key, MAX_MENU_CHAR_WIDTH, 4), + wrap_help_text(key, MAX_MENU_CHAR_WIDTH, 4), wrap_help_text(&val.description, MAX_MENU_CHAR_WIDTH, 8), empty_bar ); @@ -715,7 +715,7 @@ impl CommandHandler { { None => println!("Battery status for device {} could not be fetched", address), Some(set) => { - if set.batteries.len() == 0 { + if set.batteries.is_empty() { println!("Battery set for device {} is empty", set.address.to_string()); return Ok(()); } @@ -751,7 +751,7 @@ impl CommandHandler { } println!("Stopped tracking {}", address); - if self.lock_context().battery_address_filter.len() == 0 { + if self.lock_context().battery_address_filter.is_empty() { println!("No longer tracking any addresses for battery status updates"); return Ok(()); } @@ -997,7 +997,7 @@ impl CommandHandler { let (accept, pin) = match (&pin[..], pin) { ("reject", _) => (false, vec![]), - (_, p) => (true, p.as_bytes().iter().cloned().collect::>()), + (_, p) => (true, p.as_bytes().to_vec()), }; self.lock_context().adapter_dbus.as_mut().unwrap().set_pin( @@ -1248,7 +1248,7 @@ impl CommandHandler { } }; - let value = hex::decode(&get_arg(args, 4)?).or(Err("Failed to parse value"))?; + let value = hex::decode(get_arg(args, 4)?).or(Err("Failed to parse value"))?; let client_id = self .lock_context() @@ -1499,7 +1499,7 @@ impl CommandHandler { }; self.lock_context().gatt_dbus.as_mut().unwrap().send_response( server_id, - request.address.clone(), + request.address, request.id, status, request.offset, @@ -1603,11 +1603,11 @@ impl CommandHandler { return Err(self.adapter_not_ready()); } - if self.lock_context().advertiser_callback_id == None { + if self.lock_context().advertiser_callback_id.is_none() { return Err("No advertiser callback registered".into()); } - let callback_id = self.lock_context().advertiser_callback_id.clone().unwrap(); + let callback_id = self.lock_context().advertiser_callback_id.unwrap(); let command = get_arg(args, 0)?; @@ -1627,7 +1627,7 @@ impl CommandHandler { } "set-interval" => { let ms = String::from(get_arg(args, 1)?).parse::(); - if !ms.is_ok() { + if ms.is_err() { return Err("Failed parsing interval".into()); } let interval = ms.unwrap() * 8 / 5; // in 0.625 ms. @@ -1641,7 +1641,7 @@ impl CommandHandler { let advs: Vec<(_, _)> = context .adv_sets .iter() - .filter_map(|(_, s)| s.adv_id.map(|adv_id| (adv_id.clone(), s.params.clone()))) + .filter_map(|(_, s)| s.adv_id.map(|adv_id| (adv_id, s.params.clone()))) .collect(); for (adv_id, params) in advs { print_info!("Setting advertising parameters for {}", adv_id); @@ -1696,8 +1696,7 @@ impl CommandHandler { .adv_sets .iter() .filter_map(|(_, s)| { - s.adv_id - .map(|adv_id| (adv_id.clone(), s.params.clone(), s.scan_rsp.clone())) + s.adv_id.map(|adv_id| (adv_id, s.params.clone(), s.scan_rsp.clone())) }) .collect(); for (adv_id, params, scan_rsp) in advs { @@ -1715,11 +1714,7 @@ impl CommandHandler { .or(Err("Failed parsing adv_id"))?; let mut context = self.context.lock().unwrap(); - if context - .adv_sets - .iter() - .find(|(_, s)| s.adv_id.map_or(false, |id| id == adv_id)) - .is_none() + if !context.adv_sets.iter().any(|(_, s)| s.adv_id.map_or(false, |id| id == adv_id)) { return Err("Failed to find advertising set".into()); } @@ -1763,7 +1758,7 @@ impl CommandHandler { return Err(self.adapter_not_ready()); } - let callback_id = match self.lock_context().socket_manager_callback_id.clone() { + let callback_id = match self.lock_context().socket_manager_callback_id { Some(id) => id, None => { return Err("No socket manager callback registered.".into()); @@ -1845,12 +1840,10 @@ impl CommandHandler { } else { proxy.listen_using_l2cap_channel(callback_id) } + } else if is_le { + proxy.listen_using_insecure_l2cap_le_channel(callback_id) } else { - if is_le { - proxy.listen_using_insecure_l2cap_le_channel(callback_id) - } else { - proxy.listen_using_insecure_l2cap_channel(callback_id) - } + proxy.listen_using_insecure_l2cap_channel(callback_id) } }; @@ -1905,21 +1898,19 @@ impl CommandHandler { } else { proxy.create_l2cap_channel(callback_id, device, psm) } + } else if is_le { + proxy.create_insecure_l2cap_le_channel(callback_id, device, psm) } else { - if is_le { - proxy.create_insecure_l2cap_le_channel(callback_id, device, psm) - } else { - proxy.create_insecure_l2cap_channel(callback_id, device, psm) - } + proxy.create_insecure_l2cap_channel(callback_id, device, psm) } } "rfcomm" => { let uuid = match Uuid::from_string(*psm_or_uuid) { Some(uu) => uu, None => { - return Err(CommandError::Failed(format!( - "Could not parse given uuid." - ))); + return Err(CommandError::Failed( + "Could not parse given uuid.".to_string(), + )); } }; @@ -2118,7 +2109,7 @@ impl CommandHandler { let strength = String::from(get_arg(args, 1)?) .parse::() .or(Err("Failed parsing signal strength"))?; - if strength < 0 || strength > 5 { + if !(0..=5).contains(&strength) { return Err( format!("Invalid signal strength, got {}, want 0 to 5", strength).into() ); @@ -2135,7 +2126,7 @@ impl CommandHandler { let level = String::from(get_arg(args, 1)?) .parse::() .or(Err("Failed parsing battery level"))?; - if level < 0 || level > 5 { + if !(0..=5).contains(&level) { return Err(format!("Invalid battery level, got {}, want 0 to 5", level).into()); } self.context @@ -2156,7 +2147,7 @@ impl CommandHandler { .unwrap() .create_sdp_record(BtSdpRecord::Mps(BtSdpMpsRecord::default())); if !success { - return Err(format!("Failed to create SDP record").into()); + return Err("Failed to create SDP record".to_string().into()); } } } @@ -2166,7 +2157,7 @@ impl CommandHandler { if let Some(handle) = context.mps_sdp_handle.take() { let success = context.adapter_dbus.as_mut().unwrap().remove_sdp_record(handle); if !success { - return Err(format!("Failed to remove SDP record").into()); + return Err("Failed to remove SDP record".to_string().into()); } } } diff --git a/system/gd/rust/linux/client/src/dbus_iface.rs b/system/gd/rust/linux/client/src/dbus_iface.rs index 6a2fe45b119..2f7db863264 100644 --- a/system/gd/rust/linux/client/src/dbus_iface.rs +++ b/system/gd/rust/linux/client/src/dbus_iface.rs @@ -235,7 +235,7 @@ where key, stringify!(T), ))))?, - format!("{}", stringify!(T)), + stringify!(T).to_string(), )?; let output = T::from_dbus(output, None, None, None)?; Ok(output) @@ -509,11 +509,11 @@ impl DBusArg for ScanFilterCondition { let patterns = < as DBusArg>::DBusType as RefArgToRust>::ref_arg_to_rust( variant.as_static_inner(0).unwrap(), - format!("ScanFilterCondition::Patterns"), + "ScanFilterCondition::Patterns".to_string(), )?; let patterns = Vec::::from_dbus(patterns, None, None, None)?; - return Ok(ScanFilterCondition::Patterns(patterns)); + Ok(ScanFilterCondition::Patterns(patterns)) } fn to_dbus( @@ -529,7 +529,7 @@ impl DBusArg for ScanFilterCondition { } _ => {} } - return Ok(map); + Ok(map) } // We don't log in btclient. @@ -1141,7 +1141,7 @@ impl BluetoothManagerDBus { pub(crate) fn is_valid(&self) -> bool { let result: Result<(bool,), _> = self.client_proxy.method_withresult("GetFlossEnabled", ()); - return result.is_ok(); + result.is_ok() } } diff --git a/system/gd/rust/linux/client/src/editor.rs b/system/gd/rust/linux/client/src/editor.rs index 1e5d5e2021a..0b2ef64d20f 100644 --- a/system/gd/rust/linux/client/src/editor.rs +++ b/system/gd/rust/linux/client/src/editor.rs @@ -84,19 +84,19 @@ impl BtHelper { let mut result = HashSet::::new(); for rule in self.command_rules.iter() { - let n_splits = cmd.split(" ").count(); + let n_splits = cmd.split(' ').count(); // The tokens should have empty strings removed from them, except the last one. let tokens = cmd - .split(" ") + .split(' ') .enumerate() - .filter_map(|(i, token)| (i == n_splits - 1 || token != "").then(|| token)); + .filter_map(|(i, token)| (i == n_splits - 1 || !token.is_empty()).then_some(token)); let n_cmd = tokens.clone().count(); - for (i, (rule_token, cmd_token)) in rule.split(" ").zip(tokens).enumerate() { + for (i, (rule_token, cmd_token)) in rule.split(' ').zip(tokens).enumerate() { let mut candidates = Vec::::new(); let mut match_some = false; - for opt in rule_token.replace("<", "").replace(">", "").split("|") { + for opt in rule_token.replace(['<', '>'], "").split('|') { if opt.eq("address") { let devices = self.client_context.lock().unwrap().get_devices(); candidates.extend(devices); @@ -105,7 +105,7 @@ impl BtHelper { } } - if cmd_token.len() == 0 { + if cmd_token.is_empty() { candidates.iter().for_each(|s| { result.insert(CommandCandidate { suggest_word: s.clone(), matched_len: 0 }); }); diff --git a/system/gd/rust/linux/client/src/main.rs b/system/gd/rust/linux/client/src/main.rs index 8aef720d0b9..91840597069 100644 --- a/system/gd/rust/linux/client/src/main.rs +++ b/system/gd/rust/linux/client/src/main.rs @@ -283,7 +283,7 @@ impl ClientContext { // Foreground-only: Updates the adapter address. fn update_adapter_address(&mut self) -> RawAddress { let address = self.adapter_dbus.as_ref().unwrap().get_address(); - self.adapter_address = Some(address.clone()); + self.adapter_address = Some(address); address } @@ -314,14 +314,12 @@ impl ClientContext { fn get_devices(&self) -> Vec { let mut result: Vec = vec![]; - result.extend( - self.found_devices.keys().map(|key| String::from(key)).collect::>(), - ); + result.extend(self.found_devices.keys().map(String::from).collect::>()); result.extend( self.bonded_devices .keys() .filter(|key| !self.found_devices.contains_key(&String::from(*key))) - .map(|key| String::from(key)) + .map(String::from) .collect::>(), ); @@ -450,7 +448,7 @@ fn main() -> Result<(), Box> { } let handler = CommandHandler::new(context.clone()); - if let Ok(_) = command { + if command.is_ok() { // Timeout applies only to non-interactive commands. if let Ok(timeout_secs) = timeout_secs { let timeout_duration = Duration::from_secs(timeout_secs); @@ -473,7 +471,7 @@ fn main() -> Result<(), Box> { // - Interactive commands: none of these commands require a timeout. // - Non-interactive commands that have not specified a timeout. handle_client_command(handler, tx, rx, context, command).await?; - return Result::Ok(()); + Result::Ok(()) }) } @@ -496,7 +494,7 @@ async fn handle_client_command( let semaphore_fg = Arc::new(tokio::sync::Semaphore::new(1)); // If there are no command arguments, start the interactive shell. - if let Err(_) = command { + if command.is_err() { let command_rule_list = handler.get_command_rule_list().clone(); let context_for_closure = context.clone(); @@ -546,7 +544,7 @@ async fn handle_client_command( callback(context.clone()); // Break the loop as a non-interactive command is completed. - if let Ok(_) = command { + if command.is_ok() { break; } } @@ -763,7 +761,7 @@ async fn handle_client_command( // Run the command with the command arguments as the client is // non-interactive. - if let Some(command) = command.as_ref().ok() { + if let Ok(command) = command.as_ref() { let mut iter = command.split(' ').map(String::from); let first = iter.next().unwrap_or(String::from("")); if !handler.process_cmd_line(&first, &iter.collect::>()) { diff --git a/system/gd/rust/linux/mgmt/src/bluetooth_manager.rs b/system/gd/rust/linux/mgmt/src/bluetooth_manager.rs index 81473e1d98c..41ffb358e91 100644 --- a/system/gd/rust/linux/mgmt/src/bluetooth_manager.rs +++ b/system/gd/rust/linux/mgmt/src/bluetooth_manager.rs @@ -161,7 +161,7 @@ impl IBluetoothManager for BluetoothManager { config_util::write_floss_enabled(enabled); if prev != enabled && enabled { - if let Err(e) = Command::new("initctl").args(&["stop", BLUEZ_INIT_TARGET]).output() { + if let Err(e) = Command::new("initctl").args(["stop", BLUEZ_INIT_TARGET]).output() { warn!("Failed to stop bluetoothd: {}", e); } migrate::migrate_bluez_devices(); @@ -177,7 +177,7 @@ impl IBluetoothManager for BluetoothManager { } } migrate::migrate_floss_devices(); - if let Err(e) = Command::new("initctl").args(&["start", BLUEZ_INIT_TARGET]).output() { + if let Err(e) = Command::new("initctl").args(["start", BLUEZ_INIT_TARGET]).output() { warn!("Failed to start bluetoothd: {}", e); } } @@ -230,7 +230,7 @@ fn config_with_le_device_entry(filename: &str) -> bool { }; for (sec, props) in floss_map { // Skip all the non-device sections - if !sec.contains(":") { + if !sec.contains(':') { continue; } // Invalid entries have no DevType @@ -247,7 +247,7 @@ fn config_with_le_device_entry(filename: &str) -> bool { } } } - return false; + false } /// Check if there are any LE Floss devices in storage. @@ -265,7 +265,7 @@ fn floss_have_le_devices() -> bool { return true; } } - return false; + false } /// Implementation of IBluetoothExperimental @@ -305,7 +305,7 @@ impl IBluetoothExperimental for BluetoothManager { self.restart_adapters(); } - return true; + true } fn set_devcoredump(&mut self, enabled: bool) -> bool { diff --git a/system/gd/rust/linux/mgmt/src/config_util.rs b/system/gd/rust/linux/mgmt/src/config_util.rs index 8b456ad3354..acce9ed08e9 100644 --- a/system/gd/rust/linux/mgmt/src/config_util.rs +++ b/system/gd/rust/linux/mgmt/src/config_util.rs @@ -138,7 +138,7 @@ pub fn get_default_adapter() -> VirtualHciIndex { .try_into() .ok() }) - .map(|i| VirtualHciIndex(i)) + .map(VirtualHciIndex) .unwrap_or(DEFAULT_ADAPTER) } @@ -310,18 +310,15 @@ mod tests { get_log_level_internal("{\"log_level\": \"trace\"}".to_string()).unwrap(), LevelFilter::Trace ); - assert_eq!( - get_log_level_internal("{\"log_level\": \"random\"}".to_string()).is_none(), - true - ); + assert!(get_log_level_internal("{\"log_level\": \"random\"}".to_string()).is_none()); } #[test] fn parse_hci0_enabled() { - assert_eq!( - is_hci_n_enabled_internal_wrapper("{\"hci0\":\n{\"enabled\": true}}".to_string(), 0), - true - ); + assert!(is_hci_n_enabled_internal_wrapper( + "{\"hci0\":\n{\"enabled\": true}}".to_string(), + 0 + )); } #[test] @@ -332,29 +329,29 @@ mod tests { true, ) .unwrap(); - assert_eq!(is_hci_n_enabled_internal_wrapper(modified_string, 0), true); + assert!(is_hci_n_enabled_internal_wrapper(modified_string, 0)); } #[test] fn modify_hci0_enabled_from_empty() { let modified_string = modify_hci_n_enabled_internal("{}".to_string(), VirtualHciIndex(0), true).unwrap(); - assert_eq!(is_hci_n_enabled_internal_wrapper(modified_string, 0), true); + assert!(is_hci_n_enabled_internal_wrapper(modified_string, 0)); } #[test] fn parse_hci0_not_enabled() { - assert_eq!( - is_hci_n_enabled_internal_wrapper("{\"hci0\":\n{\"enabled\": false}}".to_string(), 0), - false - ); + assert!(!is_hci_n_enabled_internal_wrapper( + "{\"hci0\":\n{\"enabled\": false}}".to_string(), + 0 + )); } #[test] fn parse_hci1_not_present() { - assert_eq!( - is_hci_n_enabled_internal_wrapper("{\"hci0\":\n{\"enabled\": true}}".to_string(), 1), - true - ); + assert!(is_hci_n_enabled_internal_wrapper( + "{\"hci0\":\n{\"enabled\": true}}".to_string(), + 1 + )); } } diff --git a/system/gd/rust/linux/mgmt/src/main.rs b/system/gd/rust/linux/mgmt/src/main.rs index 7c2d9633f49..31291122254 100644 --- a/system/gd/rust/linux/mgmt/src/main.rs +++ b/system/gd/rust/linux/mgmt/src/main.rs @@ -105,7 +105,7 @@ pub async fn main() -> Result<(), Box> { // InterfaceAdded and InterfaceRemoved signals. cr.lock().unwrap().set_object_manager_support(Some(conn.clone())); let om = cr.lock().unwrap().object_manager(); - cr.lock().unwrap().insert("/", &[om], {}); + cr.lock().unwrap().insert("/", &[om], ()); let bluetooth_manager = Arc::new(Mutex::new(Box::new(BluetoothManager::new(proxy)))); diff --git a/system/gd/rust/linux/mgmt/src/migrate.rs b/system/gd/rust/linux/mgmt/src/migrate.rs index f42f2f6dd6b..e1a0a9aa51d 100644 --- a/system/gd/rust/linux/mgmt/src/migrate.rs +++ b/system/gd/rust/linux/mgmt/src/migrate.rs @@ -187,7 +187,7 @@ struct DeviceKey { impl DeviceKey { /// Returns a DeviceKey with the key and action given fn new(key: &'static str, action: KeyAction) -> Self { - Self { key: key, action: action, section: "" } + Self { key, action, section: "" } } /// Performs the KeyAction stored and returns the result of the key conversion @@ -205,8 +205,8 @@ impl DeviceKey { Converter::AddrTypeF2B => floss_to_bluez_addr_type(value), Converter::ReverseEndianLowercase => reverse_endianness(value, false), Converter::ReverseEndianUppercase => reverse_endianness(value, true), - Converter::ReplaceSemiColonWithSpace => Ok(value.replace(";", " ")), - Converter::ReplaceSpaceWithSemiColon => Ok(value.replace(" ", ";")), + Converter::ReplaceSemiColonWithSpace => Ok(value.replace(';', " ")), + Converter::ReplaceSpaceWithSemiColon => Ok(value.replace(' ', ";")), } } @@ -371,7 +371,7 @@ fn convert_from_bluez_device( floss_conf.set( addr_lower.as_str(), "LE_KEY_PID", - Some(format!("{}{:02x}{}", irk, addr_type, addr_lower.replace(":", ""))), + Some(format!("{}{:02x}{}", irk, addr_type, addr_lower.replace(':', ""))), ); true } @@ -574,13 +574,13 @@ pub fn migrate_bluez_devices() { let devices = conf.sections(); for (sec, props) in ini { // Drop devices that don't exist in BlueZ - if sec.contains(":") && !devices.contains(&sec) { + if sec.contains(':') && !devices.contains(&sec) { info!("Dropping a device in Floss that doesn't exist in BlueZ"); continue; } // Keep keys that weren't transferrable for (k, v) in props { - if conf.get(sec.as_str(), k.as_str()) == None { + if conf.get(sec.as_str(), k.as_str()).is_none() { conf.set(sec.as_str(), k.as_str(), v); } } @@ -622,7 +622,7 @@ fn merge_and_write_bluez_conf(filepath: String, conf: &mut Ini) { for (sec, props) in ini { // Keep keys that weren't transferrable for (k, v) in props { - if conf.get(sec.as_str(), k.as_str()) == None { + if conf.get(sec.as_str(), k.as_str()).is_none() { conf.set(sec.as_str(), k.as_str(), v); } } @@ -748,7 +748,7 @@ fn convert_floss_conf(filename: &str) { let mut devices: Vec = Vec::new(); for (sec, props) in floss_map { // Skip all the non-adapter sections - if !sec.contains(":") { + if !sec.contains(':') { continue; } // Keep track of Floss devices we've seen so we can remove BlueZ devices that don't exist on Floss @@ -1137,24 +1137,18 @@ mod tests { fn test_convert_from_bluez_device() { let test_addr = "00:11:22:33:44:55"; let mut conf = Ini::new_cs(); - assert_eq!( - convert_from_bluez_device( - "test/migrate/fake_bluez_info.toml", - test_addr, - &mut conf, - false - ), - true - ); - assert_eq!( - convert_from_bluez_device( - "test/migrate/fake_bluez_hid.toml", - test_addr, - &mut conf, - true - ), + assert!(convert_from_bluez_device( + "test/migrate/fake_bluez_info.toml", + test_addr, + &mut conf, + false + )); + assert!(convert_from_bluez_device( + "test/migrate/fake_bluez_hid.toml", + test_addr, + &mut conf, true - ); + )); assert_eq!(conf.get(test_addr, "Name"), Some(String::from("Test Device"))); assert_eq!(conf.get(test_addr, "DevClass"), Some(String::from("2360344"))); diff --git a/system/gd/rust/linux/mgmt/src/powerd_suspend_manager.rs b/system/gd/rust/linux/mgmt/src/powerd_suspend_manager.rs index 0e0edb65027..9db0041d3ed 100644 --- a/system/gd/rust/linux/mgmt/src/powerd_suspend_manager.rs +++ b/system/gd/rust/linux/mgmt/src/powerd_suspend_manager.rs @@ -219,7 +219,7 @@ impl PowerdSuspendManager { } pub fn get_suspend_manager_context(&mut self) -> Arc> { - return self.context.clone(); + self.context.clone() } /// Sets up all required D-Bus listeners. @@ -552,7 +552,7 @@ impl PowerdSuspendManager { let context = self.context.clone(); tokio::spawn(async move { let suspend_cb_objpath: String = - format!("/org/chromium/bluetooth/Manager/suspend_callback"); + "/org/chromium/bluetooth/Manager/suspend_callback".to_string(); let status = suspend_dbus_rpc .register_callback(Box::new(SuspendCallback::new( suspend_cb_objpath, diff --git a/system/gd/rust/linux/mgmt/src/service_watcher.rs b/system/gd/rust/linux/mgmt/src/service_watcher.rs index cb6cd6726eb..4b8bb12b17a 100644 --- a/system/gd/rust/linux/mgmt/src/service_watcher.rs +++ b/system/gd/rust/linux/mgmt/src/service_watcher.rs @@ -123,10 +123,10 @@ impl ServiceWatcher { return true; } - if old_owner == "" && new_owner != "" { + if old_owner.is_empty() && !new_owner.is_empty() { context.lock().unwrap().set_owner(new_owner.clone()); on_available(); - } else if old_owner != "" && new_owner == "" { + } else if !old_owner.is_empty() && new_owner.is_empty() { context.lock().unwrap().unset_owner(); on_unavailable(); } else { diff --git a/system/gd/rust/linux/mgmt/src/state_machine.rs b/system/gd/rust/linux/mgmt/src/state_machine.rs index 320f8d4d82e..aa363774a7d 100644 --- a/system/gd/rust/linux/mgmt/src/state_machine.rs +++ b/system/gd/rust/linux/mgmt/src/state_machine.rs @@ -127,7 +127,7 @@ pub struct StateMachineContext { impl StateMachineContext { fn new(state_machine: StateMachineInternal) -> StateMachineContext { let (tx, rx) = mpsc::channel::(10); - StateMachineContext { tx: tx, rx: rx, state_machine: state_machine } + StateMachineContext { tx, rx, state_machine } } pub fn get_proxy(&self) -> StateMachineProxy { @@ -214,7 +214,7 @@ impl StateMachineProxy { F: Fn(&AdapterState) -> Option, { match self.state.lock().unwrap().get(&hci) { - Some(a) => call(&a), + Some(a) => call(a), None => None, } } @@ -290,7 +290,7 @@ fn pid_inotify_async_fd() -> AsyncFd { /// Given an pid path, returns the adapter index for that pid path. fn get_hci_index_from_pid_path(path: &str) -> Option { let re = Regex::new(r"bluetooth([0-9]+).pid").unwrap(); - re.captures(path)?.get(1)?.as_str().parse().ok().map(|v| VirtualHciIndex(v)) + re.captures(path)?.get(1)?.as_str().parse().ok().map(VirtualHciIndex) } fn event_name_to_string(name: Option<&std::ffi::OsStr>) -> Option { @@ -300,7 +300,7 @@ fn event_name_to_string(name: Option<&std::ffi::OsStr>) -> Option { } } - return None; + None } // List existing pids and then configure inotify on pid dir. @@ -312,7 +312,7 @@ fn configure_pid(pid_tx: mpsc::Sender) { // Get a list of active pid files to determine initial adapter status let files = config_util::list_pid_files(PID_DIR); for file in files { - let _ = pid_tx + pid_tx .send_timeout( Message::PidChange(inotify::EventMask::CREATE, Some(file)), TX_SEND_TIMEOUT_DURATION, @@ -333,7 +333,7 @@ fn configure_pid(pid_tx: mpsc::Sender) { Ok(Ok(events)) => { for event in events { debug!("got some events from pid {:?}", event.mask); - let _ = pid_tx + pid_tx .send_timeout( Message::PidChange(event.mask, event_name_to_string(event.name)), TX_SEND_TIMEOUT_DURATION, @@ -442,7 +442,7 @@ fn configure_hci(hci_tx: mpsc::Sender) { debug!("IndexList response: {}", hci); // We need devpath for an index or we don't use it. if let Some(d) = config_util::get_devpath_for_hci(hci) { - let _ = hci_tx + hci_tx .send_timeout( Message::AdapterStateChange( AdapterStateActions::HciDevicePresence( @@ -464,7 +464,7 @@ fn configure_hci(hci_tx: mpsc::Sender) { debug!("IndexAdded: {}", hci); // We need devpath for an index or we don't use it. if let Some(d) = config_util::get_devpath_for_hci(hci) { - let _ = hci_tx + hci_tx .send_timeout( Message::AdapterStateChange( AdapterStateActions::HciDevicePresence( @@ -483,7 +483,7 @@ fn configure_hci(hci_tx: mpsc::Sender) { let hci = RealHciIndex(hci.into()); debug!("IndexRemoved: {}", hci); let devpath = - config_util::get_devpath_for_hci(hci).unwrap_or(String::new()); + config_util::get_devpath_for_hci(hci).unwrap_or_default(); // Only send presence removed if the device is removed // and not when userchannel takes exclusive access. This needs to // be delayed a bit for when the socket legitimately disappears as @@ -496,17 +496,16 @@ fn configure_hci(hci_tx: mpsc::Sender) { tokio::spawn(async move { tokio::time::sleep(INDEX_REMOVED_DEBOUNCE_TIME).await; if !config_util::check_hci_device_exists(hci) { - let _ = txl - .send_timeout( - Message::AdapterStateChange( - AdapterStateActions::HciDevicePresence( - devpath, hci, false, - ), + txl.send_timeout( + Message::AdapterStateChange( + AdapterStateActions::HciDevicePresence( + devpath, hci, false, ), - TX_SEND_TIMEOUT_DURATION, - ) - .await - .unwrap(); + ), + TX_SEND_TIMEOUT_DURATION, + ) + .await + .unwrap(); } }); } @@ -613,7 +612,7 @@ pub async fn mainloop( let _expired = timer.expired().await; let completed = ct.lock().unwrap().expire(); for hci in completed { - let _ = timeout_tx + timeout_tx .send_timeout(Message::CommandTimeout(hci), TX_SEND_TIMEOUT_DURATION) .await .unwrap(); @@ -804,9 +803,9 @@ pub async fn mainloop( // Monitored pid directory has a change Message::PidChange(mask, filename) => match (mask, &filename) { (inotify::EventMask::CREATE, Some(fname)) => { - let path = std::path::Path::new(PID_DIR).join(&fname); + let path = std::path::Path::new(PID_DIR).join(fname); match ( - get_hci_index_from_pid_path(&fname), + get_hci_index_from_pid_path(fname), tokio::fs::read(path.clone()).await.ok(), ) { (Some(hci), Some(s)) => { @@ -815,7 +814,7 @@ pub async fn mainloop( .parse::() .unwrap_or(0); debug!("Sending bluetooth started action for {}, pid={}", hci, pid); - let _ = context + context .tx .send_timeout( Message::AdapterStateChange( @@ -869,7 +868,7 @@ pub async fn mainloop( } } (inotify::EventMask::DELETE, Some(fname)) => { - if let Some(hci) = get_hci_index_from_pid_path(&fname) { + if let Some(hci) = get_hci_index_from_pid_path(fname) { debug!("Sending bluetooth stopped action for {}", hci); context .tx @@ -961,14 +960,15 @@ pub enum Invoker { UpstartInvoker, } +#[derive(Default)] pub struct NativeInvoker { process_container: Option, bluetooth_pid: u32, } impl NativeInvoker { - pub fn new() -> NativeInvoker { - NativeInvoker { process_container: None, bluetooth_pid: 0 } + pub fn new() -> Self { + Default::default() } } @@ -995,18 +995,19 @@ impl ProcessManager for NativeInvoker { } } +#[derive(Default)] pub struct UpstartInvoker {} impl UpstartInvoker { - pub fn new() -> UpstartInvoker { - UpstartInvoker {} + pub fn new() -> Self { + Default::default() } } impl ProcessManager for UpstartInvoker { fn start(&mut self, virtual_hci: VirtualHciIndex, real_hci: RealHciIndex) { if let Err(e) = Command::new("initctl") - .args(&[ + .args([ "start", "btadapterd", format!("INDEX={}", virtual_hci.to_i32()).as_str(), @@ -1020,7 +1021,7 @@ impl ProcessManager for UpstartInvoker { fn stop(&mut self, virtual_hci: VirtualHciIndex, real_hci: RealHciIndex) { if let Err(e) = Command::new("initctl") - .args(&[ + .args([ "stop", "btadapterd", format!("INDEX={}", virtual_hci.to_i32()).as_str(), @@ -1033,18 +1034,19 @@ impl ProcessManager for UpstartInvoker { } } +#[derive(Default)] pub struct SystemdInvoker {} impl SystemdInvoker { - pub fn new() -> SystemdInvoker { - SystemdInvoker {} + pub fn new() -> Self { + Default::default() } } impl ProcessManager for SystemdInvoker { fn start(&mut self, virtual_hci: VirtualHciIndex, real_hci: RealHciIndex) { Command::new("systemctl") - .args(&[ + .args([ "restart", format!("btadapterd@{}_{}.service", virtual_hci.to_i32(), real_hci.to_i32()) .as_str(), @@ -1055,7 +1057,7 @@ impl ProcessManager for SystemdInvoker { fn stop(&mut self, virtual_hci: VirtualHciIndex, real_hci: RealHciIndex) { Command::new("systemctl") - .args(&[ + .args([ "stop", format!("btadapterd@{}_{}.service", virtual_hci.to_i32(), real_hci.to_i32()) .as_str(), @@ -1171,7 +1173,7 @@ impl StateMachineInternal { desired_adapter, state: Arc::new(Mutex::new(BTreeMap::new())), process_monitor: Arc::new(Mutex::new(HashMap::new())), - process_manager: process_manager, + process_manager, } } @@ -1188,7 +1190,7 @@ impl StateMachineInternal { .lock() .unwrap() .get(&hci_id) - .and_then(|a: &AdapterState| Some(a.real_hci)) + .map(|a: &AdapterState| a.real_hci) .unwrap_or(RealHciIndex(hci_id.to_i32())) } @@ -1200,7 +1202,7 @@ impl StateMachineInternal { for (k, v) in self.state.lock().unwrap().iter() { if v.devpath == devpath { - return Some(k.clone()); + return Some(*k); } } @@ -1211,7 +1213,7 @@ impl StateMachineInternal { pub(crate) fn get_virtual_id_by_real_id(&self, hci: RealHciIndex) -> Option { for (k, v) in self.state.lock().unwrap().iter() { if v.real_hci == hci { - return Some(k.clone()); + return Some(*k); } } @@ -1234,7 +1236,7 @@ impl StateMachineInternal { } }); - return new_virt; + new_virt } /// Identify the virtual hci for the given real hci. We need to match both @@ -1265,7 +1267,7 @@ impl StateMachineInternal { a.real_hci = RealHciIndex(INVALID_HCI_INDEX); }); - return dev; + dev } (Some(dev), None) => { // Device found by path and needs real_hci to be updated. @@ -1273,7 +1275,7 @@ impl StateMachineInternal { a.real_hci = real_hci; }); - return dev; + dev } (None, Some(real)) => { // If the real index is found but no entry exists with that devpath, @@ -1284,14 +1286,14 @@ impl StateMachineInternal { }); } - return real; + real } (None, None) => { // This is a brand new device. Add a new virtual device with this // real id and devpath. - return self.get_next_virtual_id(real_hci, Some(devpath)); + self.get_next_virtual_id(real_hci, Some(devpath)) } - }; + } // match should return on all branches above. } @@ -1381,7 +1383,7 @@ impl StateMachineInternal { // Desired adapter is either current or not present|enabled so leave the previous default // adapter. - return AdapterChangeAction::DoNothing; + AdapterChangeAction::DoNothing } /// Returns the next state and an action to reset timer if we are starting bluetooth process. @@ -1554,7 +1556,7 @@ impl StateMachineInternal { ); self.modify_state(hci, |s: &mut AdapterState| { s.state = ProcessState::TurningOn; - s.restart_count = s.restart_count + 1; + s.restart_count += 1; }); self.process_manager.start(hci, self.get_real_hci_by_virtual_id(hci)); (ProcessState::TurningOn, CommandTimeoutAction::ResetTimer) @@ -1624,7 +1626,7 @@ impl StateMachineInternal { ); self.modify_state(hci, |s: &mut AdapterState| { s.state = ProcessState::TurningOn; - s.restart_count = s.restart_count + 1; + s.restart_count += 1; }); self.process_manager.stop(hci, self.get_real_hci_by_virtual_id(hci)); self.process_manager.start(hci, self.get_real_hci_by_virtual_id(hci)); @@ -1742,7 +1744,7 @@ mod tests { Some(format!("Got [Start], Expected: [{:?}]", x)) } } - None => Some(format!("Got [Start], Expected: None")), + None => Some("Got [Start], Expected: None".to_string()), }); } @@ -1755,7 +1757,7 @@ mod tests { Some(format!("Got [Stop], Expected: [{:?}]", x)) } } - None => Some(format!("Got [Stop], Expected: None")), + None => Some("Got [Stop], Expected: None".to_string()), }); } } @@ -1782,9 +1784,7 @@ mod tests { const ALT_ADAPTER: VirtualHciIndex = VirtualHciIndex(1); fn make_state_machine(process_manager: MockProcessManager) -> StateMachineInternal { - let state_machine = - StateMachineInternal::new(Box::new(process_manager), true, DEFAULT_ADAPTER); - state_machine + StateMachineInternal::new(Box::new(process_manager), true, DEFAULT_ADAPTER) } #[test] diff --git a/system/gd/rust/linux/service/build.rs b/system/gd/rust/linux/service/build.rs index 8223fd341c9..5920f66eb24 100644 --- a/system/gd/rust/linux/service/build.rs +++ b/system/gd/rust/linux/service/build.rs @@ -29,7 +29,7 @@ fn main() { Config::new().probe("fmt").unwrap(); // Include ChromeOS-specific dependencies. - if option_env!("TARGET_OS_VARIANT").unwrap_or("None").to_string() == "chromeos" { + if option_env!("TARGET_OS_VARIANT").unwrap_or("None") == "chromeos" { Config::new().probe("libstructuredmetrics").unwrap(); } diff --git a/system/gd/rust/linux/service/src/iface_bluetooth.rs b/system/gd/rust/linux/service/src/iface_bluetooth.rs index 063b3331344..a73222009dd 100644 --- a/system/gd/rust/linux/service/src/iface_bluetooth.rs +++ b/system/gd/rust/linux/service/src/iface_bluetooth.rs @@ -50,11 +50,8 @@ impl DBusArg for Uuid { _remote: Option>, _disconnect_watcher: Option>>, ) -> Result> { - Ok(Uuid::try_from(data.clone()).or_else(|_| { - Err(format!( - "Invalid Uuid: first 4 bytes={:?}", - data.iter().take(4).collect::>() - )) + Ok(Uuid::try_from(data.clone()).map_err(|_| { + format!("Invalid Uuid: first 4 bytes={:?}", data.iter().take(4).collect::>()) })?) } @@ -63,7 +60,7 @@ impl DBusArg for Uuid { } fn log(data: &Uuid) -> String { - format!("{}", DisplayUuid(&data)) + format!("{}", DisplayUuid(data)) } } @@ -323,7 +320,7 @@ where key, stringify!(T), ))))?, - format!("{}", stringify!(T)), + stringify!(T).to_string(), )?; let output = T::from_dbus(output, None, None, None)?; Ok(output) diff --git a/system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs b/system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs index e48476c086f..d7f95ce8ef8 100644 --- a/system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs +++ b/system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs @@ -435,11 +435,11 @@ impl DBusArg for ScanFilterCondition { let patterns = < as DBusArg>::DBusType as RefArgToRust>::ref_arg_to_rust( variant.as_static_inner(0).unwrap(), - format!("ScanFilterCondition::Patterns"), + "ScanFilterCondition::Patterns".to_string(), )?; let patterns = Vec::::from_dbus(patterns, None, None, None)?; - return Ok(ScanFilterCondition::Patterns(patterns)); + Ok(ScanFilterCondition::Patterns(patterns)) } fn to_dbus( @@ -455,7 +455,7 @@ impl DBusArg for ScanFilterCondition { } _ => {} } - return Ok(map); + Ok(map) } fn log(condition: &ScanFilterCondition) -> String { diff --git a/system/gd/rust/linux/service/src/iface_bluetooth_media.rs b/system/gd/rust/linux/service/src/iface_bluetooth_media.rs index 4cbdef121f3..a38e7b07d9a 100644 --- a/system/gd/rust/linux/service/src/iface_bluetooth_media.rs +++ b/system/gd/rust/linux/service/src/iface_bluetooth_media.rs @@ -241,7 +241,7 @@ impl DBusArg for PlayerMetadata { _ => {} } } - return Ok(metadata); + Ok(metadata) } fn to_dbus( diff --git a/system/gd/rust/linux/service/src/interface_manager.rs b/system/gd/rust/linux/service/src/interface_manager.rs index 79094b6ff4d..2c027824312 100644 --- a/system/gd/rust/linux/service/src/interface_manager.rs +++ b/system/gd/rust/linux/service/src/interface_manager.rs @@ -81,7 +81,7 @@ impl InterfaceManager { // of the adapter APIs. cr.lock().unwrap().set_object_manager_support(Some(conn.clone())); let object_manager = cr.lock().unwrap().object_manager(); - cr.lock().unwrap().insert("/", &[object_manager], {}); + cr.lock().unwrap().insert("/", &[object_manager], ()); // Set up handling of D-Bus methods. This must be done before exporting interfaces so that // clients that rely on InterfacesAdded signal can rely on us being ready to handle methods diff --git a/system/gd/rust/linux/service/src/main.rs b/system/gd/rust/linux/service/src/main.rs index 496cc5b593a..31f89f7ee6f 100644 --- a/system/gd/rust/linux/service/src/main.rs +++ b/system/gd/rust/linux/service/src/main.rs @@ -98,7 +98,7 @@ fn main() -> Result<(), Box> { // The remaining flags are passed down to Fluoride as is. let mut init_flags: Vec = match matches.values_of("init-flags") { - Some(args) => args.map(|s| String::from(s)).collect(), + Some(args) => args.map(String::from).collect(), None => vec![], }; diff --git a/system/gd/rust/linux/stack/src/battery_manager.rs b/system/gd/rust/linux/stack/src/battery_manager.rs index c76f5ab3b97..e4c5a1d285e 100644 --- a/system/gd/rust/linux/stack/src/battery_manager.rs +++ b/system/gd/rust/linux/stack/src/battery_manager.rs @@ -33,6 +33,7 @@ pub struct Battery { } /// Helper representation of a collection of BatterySet to simplify passing around data internally. +#[derive(Default)] pub struct Batteries(Vec); /// Callback for interacting with the BatteryManager. @@ -123,7 +124,7 @@ impl BatterySet { impl Batteries { pub fn new() -> Self { - Self(vec![]) + Default::default() } /// Updates a battery matching all non-battery-level fields if found, otherwise adds new_battery diff --git a/system/gd/rust/linux/stack/src/battery_provider_manager.rs b/system/gd/rust/linux/stack/src/battery_provider_manager.rs index 497d664c3df..3946a4f6fc1 100644 --- a/system/gd/rust/linux/stack/src/battery_provider_manager.rs +++ b/system/gd/rust/linux/stack/src/battery_provider_manager.rs @@ -106,8 +106,7 @@ impl IBatteryProviderManager for BatteryProviderManager { return; } - let batteries = - self.battery_info.entry(battery_set.address).or_insert_with(|| Batteries::new()); + let batteries = self.battery_info.entry(battery_set.address).or_default(); batteries.add_or_update_battery_set(battery_set); if let Some(best_battery_set) = batteries.pick_best() { diff --git a/system/gd/rust/linux/stack/src/battery_service.rs b/system/gd/rust/linux/stack/src/battery_service.rs index 3d7eecd55d7..7e7ac5e6fdc 100644 --- a/system/gd/rust/linux/stack/src/battery_service.rs +++ b/system/gd/rust/linux/stack/src/battery_service.rs @@ -7,7 +7,6 @@ use crate::bluetooth_gatt::{ BluetoothGatt, BluetoothGattService, IBluetoothGatt, IBluetoothGattCallback, }; use crate::callbacks::Callbacks; -use crate::uuid::UuidHelper; use crate::Message; use crate::RPCProxy; use crate::{uuid, APIMessage, BluetoothAPI}; @@ -166,13 +165,13 @@ impl BatteryService { self.drop_device(addr); return; } - let handle = match self.get_battery_level_handle(addr.clone(), services) { + let handle = match self.get_battery_level_handle(addr, services) { Ok(battery_level_handle) => battery_level_handle, Err(status) => { if let Some(BatteryServiceStatus::BatteryServiceNotSupported) = status { self.callbacks.for_all_callbacks(|callback| { callback.on_battery_service_status_updated( - addr.clone(), + addr, BatteryServiceStatus::BatteryServiceNotSupported, ) }); @@ -188,9 +187,9 @@ impl BatteryService { return; } }; - self.handles.insert(addr, handle.clone()); + self.handles.insert(addr, handle); self.gatt.lock().unwrap().register_for_notification(client_id, addr, handle, true); - if let None = self.battery_sets.get(&addr) { + if self.battery_sets.get(&addr).is_none() { self.gatt.lock().unwrap().read_characteristic(client_id, addr, handle, 0); } } @@ -237,9 +236,9 @@ impl BatteryService { } fn set_battery_info(&mut self, remote_address: &RawAddress, value: &Vec) -> BatterySet { - let level: Vec<_> = value.iter().cloned().chain(iter::repeat(0 as u8)).take(4).collect(); + let level: Vec<_> = value.iter().cloned().chain(iter::repeat(0_u8)).take(4).collect(); let level = u32::from_le_bytes(level.try_into().unwrap()); - debug!("BAS received battery level for {}: {}", DisplayAddress(&remote_address), level); + debug!("BAS received battery level for {}: {}", DisplayAddress(remote_address), level); let battery_set = self.battery_sets.entry(*remote_address).or_insert_with(|| { BatterySet::new( *remote_address, @@ -276,7 +275,7 @@ impl BatteryService { // Let BatteryProviderManager know that BAS no longer has a battery for this device. self.battery_provider_manager.lock().unwrap().remove_battery_info( self.battery_provider_id, - remote_address.clone(), + remote_address, uuid::BAS.to_string(), ); } @@ -286,7 +285,7 @@ impl BatteryService { Some(client_id) => { self.gatt.lock().unwrap().client_disconnect(client_id, remote_address); } - None => return, + None => (), } } diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs index 7898e8b57bc..584544d05d4 100644 --- a/system/gd/rust/linux/stack/src/bluetooth.rs +++ b/system/gd/rust/linux/stack/src/bluetooth.rs @@ -806,8 +806,8 @@ impl Bluetooth { for profile in UuidHelper::get_ordered_supported_profiles() { // Only toggle initializable profiles. if let Some(enabled) = self.is_profile_enabled(&profile) { - let allowed = allowed_services.len() == 0 - || allowed_services.contains(&UuidHelper::get_profile_uuid(&profile).unwrap()); + let allowed = allowed_services.is_empty() + || allowed_services.contains(UuidHelper::get_profile_uuid(&profile).unwrap()); if allowed && !enabled { debug!("Enabling profile {}", &profile); @@ -949,7 +949,7 @@ impl Bluetooth { return false; } self.is_connectable = mode; - return true; + true } /// Returns adapter's discoverable mode. @@ -999,7 +999,7 @@ impl Bluetooth { self.set_scan_suspend_mode(SuspendMode::Suspended); - return BtStatus::Success; + BtStatus::Success } /// Exits the suspend mode for scan mode (connectable/discoverable mode). @@ -1032,7 +1032,7 @@ impl Bluetooth { // Update is only available after SuspendMode::Normal self.trigger_update_connectable_mode(); - return BtStatus::Success; + BtStatus::Success } /// Returns adapter's alias. @@ -1169,9 +1169,9 @@ impl Bluetooth { for prop in device.properties.values() { match prop { BluetoothProperty::TypeOfDevice(p) => device_type = p.clone(), - BluetoothProperty::ClassOfDevice(p) => class_of_device = p.clone(), - BluetoothProperty::Appearance(p) => appearance = p.clone(), - BluetoothProperty::VendorProductInfo(p) => vpi = p.clone(), + BluetoothProperty::ClassOfDevice(p) => class_of_device = *p, + BluetoothProperty::Appearance(p) => appearance = *p, + BluetoothProperty::VendorProductInfo(p) => vpi = *p, _ => (), } } @@ -1217,10 +1217,10 @@ impl Bluetooth { let mut props = vec![]; props.push(BluetoothProperty::BdName(result.name.clone())); props.push(BluetoothProperty::BdAddr(result.address)); - if result.service_uuids.len() > 0 { + if !result.service_uuids.is_empty() { props.push(BluetoothProperty::Uuids(result.service_uuids.clone())); } - if result.service_data.len() > 0 { + if !result.service_data.is_empty() { props.push(BluetoothProperty::Uuids( result .service_data @@ -1274,7 +1274,7 @@ impl Bluetooth { /// Creates a file to notify btmanagerd the adapter is enabled. fn create_pid_file(&self) -> std::io::Result<()> { let file_name = format!("{}/bluetooth{}.pid", PID_DIR, self.virt_index); - let mut f = File::create(&file_name)?; + let mut f = File::create(file_name)?; f.write_all(process::id().to_string().as_bytes())?; Ok(()) } @@ -1282,7 +1282,7 @@ impl Bluetooth { /// Removes the file to notify btmanagerd the adapter is disabled. fn remove_pid_file(&self) -> std::io::Result<()> { let file_name = format!("{}/bluetooth{}.pid", PID_DIR, self.virt_index); - std::fs::remove_file(&file_name)?; + std::fs::remove_file(file_name)?; Ok(()) } @@ -1311,7 +1311,7 @@ impl Bluetooth { } self.set_discovery_suspend_mode(SuspendMode::Suspended); - return BtStatus::Success; + BtStatus::Success } /// Exits the suspend mode for discovery. @@ -1327,7 +1327,7 @@ impl Bluetooth { } self.set_discovery_suspend_mode(SuspendMode::Normal); - return BtStatus::Success; + BtStatus::Success } /// Temporarily stop the discovery process and mark it as paused so that clients cannot restart @@ -1601,7 +1601,9 @@ impl BtifBluetoothCallbacks for Bluetooth { self.trigger_update_connectable_mode(); // Spawn a freshness check job in the background. - self.freshness_check.take().map(|h| h.abort()); + if let Some(h) = self.freshness_check.take() { + h.abort() + } let txl = self.tx.clone(); self.freshness_check = Some(tokio::spawn(async move { loop { @@ -1764,15 +1766,12 @@ impl BtifBluetoothCallbacks for Bluetooth { } } - if !self.is_discovering { - if self.pending_create_bond.is_some() { - debug!("Invoking delayed CreateBond"); - let tx = self.tx.clone(); - tokio::spawn(async move { - let _ = - tx.send(Message::DelayedAdapterActions(DelayedActions::CreateBond)).await; - }); - } + if !self.is_discovering && self.pending_create_bond.is_some() { + debug!("Invoking delayed CreateBond"); + let tx = self.tx.clone(); + tokio::spawn(async move { + let _ = tx.send(Message::DelayedAdapterActions(DelayedActions::CreateBond)).await; + }); } } @@ -1950,7 +1949,7 @@ impl BtifBluetoothCallbacks for Bluetooth { if !device.services_resolved { let has_uuids = properties.iter().any(|prop| match prop { - BluetoothProperty::Uuids(uu) => uu.len() > 0, + BluetoothProperty::Uuids(uu) => !uu.is_empty(), _ => false, }); @@ -2058,7 +2057,7 @@ impl BtifBluetoothCallbacks for Bluetooth { match state { BtAclState::Connected => { - let acl_reported_transport = device.acl_reported_transport.clone(); + 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()); @@ -2226,7 +2225,7 @@ impl IBluetooth for Bluetooth { fn get_bluetooth_class(&self) -> u32 { match self.properties.get(&BtPropertyType::ClassOfDevice) { Some(prop) => match prop { - BluetoothProperty::ClassOfDevice(cod) => cod.clone(), + BluetoothProperty::ClassOfDevice(cod) => *cod, _ => 0, }, _ => 0, @@ -2244,7 +2243,7 @@ impl IBluetooth for Bluetooth { fn get_discoverable_timeout(&self) -> u32 { match self.properties.get(&BtPropertyType::AdapterDiscoverableTimeout) { Some(prop) => match prop { - BluetoothProperty::AdapterDiscoverableTimeout(timeout) => timeout.clone(), + BluetoothProperty::AdapterDiscoverableTimeout(timeout) => *timeout, _ => 0, }, _ => 0, @@ -2449,7 +2448,7 @@ impl IBluetooth for Bluetooth { metrics::acl_connect_attempt(address, BtAclState::Connected); } - return BtStatus::Success; + BtStatus::Success } fn cancel_bond_process(&mut self, device: BluetoothDevice) -> bool { @@ -2484,7 +2483,7 @@ impl IBluetooth for Bluetooth { metrics::acl_connect_attempt(address, BtAclState::Disconnected); } - return true; + true } fn get_bonded_devices(&self) -> Vec { @@ -2549,21 +2548,21 @@ impl IBluetooth for Bluetooth { fn get_remote_name(&self, device: BluetoothDevice) -> String { match self.get_remote_device_property(&device, &BtPropertyType::BdName) { - Some(BluetoothProperty::BdName(name)) => return name.clone(), - _ => return "".to_string(), + Some(BluetoothProperty::BdName(name)) => name.clone(), + _ => "".to_string(), } } fn get_remote_type(&self, device: BluetoothDevice) -> BtDeviceType { match self.get_remote_device_property(&device, &BtPropertyType::TypeOfDevice) { - Some(BluetoothProperty::TypeOfDevice(device_type)) => return device_type, - _ => return BtDeviceType::Unknown, + Some(BluetoothProperty::TypeOfDevice(device_type)) => device_type, + _ => BtDeviceType::Unknown, } } fn get_remote_alias(&self, device: BluetoothDevice) -> String { match self.get_remote_device_property(&device, &BtPropertyType::RemoteFriendlyName) { - Some(BluetoothProperty::RemoteFriendlyName(name)) => return name.clone(), + Some(BluetoothProperty::RemoteFriendlyName(name)) => name.clone(), _ => "".to_string(), } } @@ -2578,7 +2577,7 @@ impl IBluetooth for Bluetooth { fn get_remote_class(&self, device: BluetoothDevice) -> u32 { match self.get_remote_device_property(&device, &BtPropertyType::ClassOfDevice) { - Some(BluetoothProperty::ClassOfDevice(class)) => return class, + Some(BluetoothProperty::ClassOfDevice(class)) => class, _ => 0, } } @@ -2610,7 +2609,7 @@ impl IBluetooth for Bluetooth { fn get_remote_vendor_product_info(&self, device: BluetoothDevice) -> BtVendorProductInfo { match self.get_remote_device_property(&device, &BtPropertyType::VendorProductInfo) { - Some(BluetoothProperty::VendorProductInfo(p)) => p.clone(), + Some(BluetoothProperty::VendorProductInfo(p)) => p, _ => BtVendorProductInfo { vendor_id_src: 0, vendor_id: 0, product_id: 0, version: 0 }, } } @@ -2828,7 +2827,7 @@ impl IBluetooth for Bluetooth { if !has_enabled_uuids { warn!("[{}] SDP hasn't completed for device, wait to connect.", DisplayAddress(&addr)); if let Some(d) = self.remote_devices.get_mut(&addr) { - if uuids.len() == 0 || !d.services_resolved { + if uuids.is_empty() || !d.services_resolved { d.wait_to_connect = true; } } @@ -2841,7 +2840,7 @@ impl IBluetooth for Bluetooth { self.resume_discovery(); } - return BtStatus::Success; + BtStatus::Success } fn disconnect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool { @@ -2943,7 +2942,7 @@ impl IBluetooth for Bluetooth { let _ = txl.send(Message::GattActions(GattActions::Disconnect(device))).await; }); - return true; + true } fn is_wbs_supported(&self) -> bool { @@ -3081,7 +3080,7 @@ impl BtifHHCallbacks for Bluetooth { _ => { if self .get_remote_uuids(device) - .contains(&UuidHelper::get_profile_uuid(&Profile::Hogp).unwrap()) + .contains(UuidHelper::get_profile_uuid(&Profile::Hogp).unwrap()) { Profile::Hogp } else { diff --git a/system/gd/rust/linux/stack/src/bluetooth_admin.rs b/system/gd/rust/linux/stack/src/bluetooth_admin.rs index fa1d503ee74..e42822314cd 100644 --- a/system/gd/rust/linux/stack/src/bluetooth_admin.rs +++ b/system/gd/rust/linux/stack/src/bluetooth_admin.rs @@ -128,9 +128,8 @@ impl BluetoothAdmin { fn write_config(&self) -> Result<()> { let mut f = File::create(&self.path)?; - f.write_all(self.get_config_string().as_bytes()).and_then(|_| { + f.write_all(self.get_config_string().as_bytes()).map(|_| { info!("Write settings into {} successfully", &self.path); - Ok(()) }) } diff --git a/system/gd/rust/linux/stack/src/bluetooth_adv.rs b/system/gd/rust/linux/stack/src/bluetooth_adv.rs index 727954e697a..86049a36030 100644 --- a/system/gd/rust/linux/stack/src/bluetooth_adv.rs +++ b/system/gd/rust/linux/stack/src/bluetooth_adv.rs @@ -210,44 +210,44 @@ const INVALID_ADV_ID: i32 = 0xff; // Invalid advertising set id. pub const INVALID_REG_ID: i32 = -1; -impl Into for AdvertisingSetParameters { - fn into(self) -> bt_topshim::profiles::gatt::AdvertiseParameters { +impl From for bt_topshim::profiles::gatt::AdvertiseParameters { + fn from(val: AdvertisingSetParameters) -> Self { let mut props: u16 = 0; - if self.connectable { + if val.connectable { props |= 0x01; } - if self.scannable { + if val.scannable { props |= 0x02; } - if self.is_legacy { + if val.is_legacy { props |= 0x10; } - if self.is_anonymous { + if val.is_anonymous { props |= 0x20; } - if self.include_tx_power { + if val.include_tx_power { props |= 0x40; } - match self.discoverable { + match val.discoverable { LeDiscMode::GeneralDiscoverable => { props |= 0x04; } _ => {} } - let interval = clamp(self.interval, INTERVAL_MIN, INTERVAL_MAX - INTERVAL_DELTA); + let interval = clamp(val.interval, INTERVAL_MIN, INTERVAL_MAX - INTERVAL_DELTA); bt_topshim::profiles::gatt::AdvertiseParameters { advertising_event_properties: props, min_interval: interval as u32, max_interval: (interval + INTERVAL_DELTA) as u32, - channel_map: 0x07 as u8, // all channels - tx_power: self.tx_power_level as i8, - primary_advertising_phy: self.primary_phy.into(), - secondary_advertising_phy: self.secondary_phy.into(), - scan_request_notification_enable: 0 as u8, // false - own_address_type: self.own_address_type as i8, + channel_map: 0x07_u8, // all channels + tx_power: val.tx_power_level as i8, + primary_advertising_phy: val.primary_phy.into(), + secondary_advertising_phy: val.secondary_phy.into(), + scan_request_notification_enable: 0_u8, // false + own_address_type: val.own_address_type as i8, } } } @@ -281,9 +281,9 @@ impl AdvertiseData { } } - let bytes_list = vec![uuid16_bytes, uuid32_bytes, uuid128_bytes]; + let bytes_list = [uuid16_bytes, uuid32_bytes, uuid128_bytes]; for (ad_type, bytes) in - ad_types.iter().zip(bytes_list.iter()).filter(|(_, bytes)| bytes.len() > 0) + ad_types.iter().zip(bytes_list.iter()).filter(|(_, bytes)| !bytes.is_empty()) { AdvertiseData::append_adv_data(dest, *ad_type, bytes); } @@ -313,7 +313,7 @@ impl AdvertiseData { } fn append_device_name(dest: &mut Vec, device_name: &String) { - if device_name.len() == 0 { + if device_name.is_empty() { return; } @@ -336,8 +336,8 @@ impl AdvertiseData { dest: &mut Vec, transport_discovery_data: &Vec>, ) { - for tdd in transport_discovery_data.iter().filter(|tdd| tdd.len() > 0) { - AdvertiseData::append_adv_data(dest, TRANSPORT_DISCOVERY_DATA, &tdd); + for tdd in transport_discovery_data.iter().filter(|tdd| !tdd.is_empty()) { + AdvertiseData::append_adv_data(dest, TRANSPORT_DISCOVERY_DATA, tdd); } } @@ -376,14 +376,14 @@ impl AdvertiseData { } } -impl Into - for PeriodicAdvertisingParameters +impl From + for bt_topshim::profiles::gatt::PeriodicAdvertisingParameters { - fn into(self) -> bt_topshim::profiles::gatt::PeriodicAdvertisingParameters { + fn from(val: PeriodicAdvertisingParameters) -> Self { let mut p = bt_topshim::profiles::gatt::PeriodicAdvertisingParameters::default(); let interval = clamp( - self.interval, + val.interval, PERIODIC_INTERVAL_MIN, PERIODIC_INTERVAL_MAX - PERIODIC_INTERVAL_DELTA, ); @@ -392,7 +392,7 @@ impl Into p.include_adi = false; p.min_interval = interval as u16; p.max_interval = p.min_interval + (PERIODIC_INTERVAL_DELTA as u16); - if self.include_tx_power { + if val.include_tx_power { p.periodic_advertising_properties |= 0x40; } @@ -625,7 +625,7 @@ impl AdvertiseManagerImpl { return Some(s.reg_id()); } } - return None; + None } /// Returns a mutable reference to the advertising set with the reg_id specified. @@ -955,7 +955,7 @@ impl IBluetoothAdvertiseManager for AdvertiseManagerImpl { fn stop_advertising_set(&mut self, advertiser_id: i32) { let s = if let Some(s) = self.get_by_advertiser_id(advertiser_id) { - s.clone() + *s } else { return; }; @@ -1258,15 +1258,13 @@ impl BtifGattAdvCallbacks for AdvertiseManagerImpl { return; } - let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + let s = *self.get_by_advertiser_id(advertiser_id).unwrap(); if let Some(cb) = self.get_callback(&s) { cb.on_advertising_enabled(advertiser_id, enabled, status); } - if self.suspend_mode() == SuspendMode::Suspending { - if self.enabled_sets().count() == 0 { - self.set_suspend_mode(SuspendMode::Suspended); - } + if self.suspend_mode() == SuspendMode::Suspending && self.enabled_sets().count() == 0 { + self.set_suspend_mode(SuspendMode::Suspended); } } @@ -1274,10 +1272,10 @@ impl BtifGattAdvCallbacks for AdvertiseManagerImpl { debug!("on_advertising_data_set(): adv_id = {}, status = {:?}", adv_id, status); let advertiser_id: i32 = adv_id.into(); - if None == self.get_by_advertiser_id(advertiser_id) { + if self.get_by_advertiser_id(advertiser_id).is_none() { return; } - let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + let s = *self.get_by_advertiser_id(advertiser_id).unwrap(); if let Some(cb) = self.get_callback(&s) { cb.on_advertising_data_set(advertiser_id, status); @@ -1288,10 +1286,10 @@ impl BtifGattAdvCallbacks for AdvertiseManagerImpl { debug!("on_scan_response_data_set(): adv_id = {}, status = {:?}", adv_id, status); let advertiser_id: i32 = adv_id.into(); - if None == self.get_by_advertiser_id(advertiser_id) { + if self.get_by_advertiser_id(advertiser_id).is_none() { return; } - let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + let s = *self.get_by_advertiser_id(advertiser_id).unwrap(); if let Some(cb) = self.get_callback(&s) { cb.on_scan_response_data_set(advertiser_id, status); @@ -1310,10 +1308,10 @@ impl BtifGattAdvCallbacks for AdvertiseManagerImpl { ); let advertiser_id: i32 = adv_id.into(); - if None == self.get_by_advertiser_id(advertiser_id) { + if self.get_by_advertiser_id(advertiser_id).is_none() { return; } - let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + let s = *self.get_by_advertiser_id(advertiser_id).unwrap(); if let Some(cb) = self.get_callback(&s) { cb.on_advertising_parameters_updated(advertiser_id, tx_power.into(), status); @@ -1331,10 +1329,10 @@ impl BtifGattAdvCallbacks for AdvertiseManagerImpl { ); let advertiser_id: i32 = adv_id.into(); - if None == self.get_by_advertiser_id(advertiser_id) { + if self.get_by_advertiser_id(advertiser_id).is_none() { return; } - let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + let s = *self.get_by_advertiser_id(advertiser_id).unwrap(); if let Some(cb) = self.get_callback(&s) { cb.on_periodic_advertising_parameters_updated(advertiser_id, status); @@ -1345,10 +1343,10 @@ impl BtifGattAdvCallbacks for AdvertiseManagerImpl { debug!("on_periodic_advertising_data_set(): adv_id = {}, status = {:?}", adv_id, status); let advertiser_id: i32 = adv_id.into(); - if None == self.get_by_advertiser_id(advertiser_id) { + if self.get_by_advertiser_id(advertiser_id).is_none() { return; } - let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + let s = *self.get_by_advertiser_id(advertiser_id).unwrap(); if let Some(cb) = self.get_callback(&s) { cb.on_periodic_advertising_data_set(advertiser_id, status); @@ -1367,10 +1365,10 @@ impl BtifGattAdvCallbacks for AdvertiseManagerImpl { ); let advertiser_id: i32 = adv_id.into(); - if None == self.get_by_advertiser_id(advertiser_id) { + if self.get_by_advertiser_id(advertiser_id).is_none() { return; } - let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + let s = *self.get_by_advertiser_id(advertiser_id).unwrap(); if let Some(cb) = self.get_callback(&s) { cb.on_periodic_advertising_enabled(advertiser_id, enabled, status); @@ -1386,10 +1384,10 @@ impl BtifGattAdvCallbacks for AdvertiseManagerImpl { ); let advertiser_id: i32 = adv_id.into(); - if None == self.get_by_advertiser_id(advertiser_id) { + if self.get_by_advertiser_id(advertiser_id).is_none() { return; } - let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone(); + let s = *self.get_by_advertiser_id(advertiser_id).unwrap(); if let Some(cb) = self.get_callback(&s) { cb.on_own_address_read(advertiser_id, addr_type.into(), address); @@ -1524,9 +1522,9 @@ impl SoftwareRotationAdvertiseManagerImpl { if info.expire_time.map_or(false, |t| t < now) { // This advertiser has expired. info.enabled = false; - callbacks.get_by_id_mut(info.callback_id).map(|cb| { + if let Some(cb) = callbacks.get_by_id_mut(info.callback_id) { cb.on_advertising_enabled(info.id, false, AdvertisingStatus::Success); - }); + } } info.enabled }); @@ -1757,9 +1755,9 @@ impl IBluetoothAdvertiseManager for SoftwareRotationAdvertiseManagerImpl { warn!("stop_advertising_set: Unknown adv_id {}", adv_id); return; }; - self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) { cb.on_advertising_set_stopped(info.id); - }); + } if current_id == Some(info.id) { self.run_rotate(); } @@ -1799,9 +1797,9 @@ impl IBluetoothAdvertiseManager for SoftwareRotationAdvertiseManagerImpl { if enable && !self.adv_queue.contains(&info.id) && current_id != Some(info.id) { // The adv was not enabled and not in the queue. Invoke callback and queue it. - self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) { cb.on_advertising_enabled(info.id, false, AdvertisingStatus::Success); - }); + } self.adv_queue.push_back(info.id); if self.is_stopped() { self.start_next_advertising(); @@ -1828,9 +1826,9 @@ impl IBluetoothAdvertiseManager for SoftwareRotationAdvertiseManagerImpl { return; } info.advertising_data = data; - self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) { cb.on_advertising_data_set(info.id, AdvertisingStatus::Success); - }); + } if current_id == Some(info.id) { self.run_rotate(); @@ -1852,9 +1850,9 @@ impl IBluetoothAdvertiseManager for SoftwareRotationAdvertiseManagerImpl { return; } info.advertising_data = data; - self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) { cb.on_advertising_data_set(info.id, AdvertisingStatus::Success); - }); + } if current_id == Some(info.id) { self.run_rotate(); @@ -1878,9 +1876,9 @@ impl IBluetoothAdvertiseManager for SoftwareRotationAdvertiseManagerImpl { return; } info.scan_response_data = data; - self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) { cb.on_scan_response_data_set(info.id, AdvertisingStatus::Success); - }); + } if current_id == Some(info.id) { self.run_rotate(); @@ -1902,9 +1900,9 @@ impl IBluetoothAdvertiseManager for SoftwareRotationAdvertiseManagerImpl { error!("set_advertising_parameters: tx_power is None! Is this called before adv has started?"); return; }; - self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) { cb.on_advertising_parameters_updated(info.id, tx_power, AdvertisingStatus::Success); - }); + } if current_id == Some(info.id) { self.run_rotate(); @@ -1982,16 +1980,16 @@ impl BtifGattAdvCallbacks for SoftwareRotationAdvertiseManagerImpl { if info.tx_power.is_none() { // tx_power is none means it's the first time this advertiser started. if status != AdvertisingStatus::Success { - self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) { cb.on_advertising_set_started(info.id, INVALID_ADV_ID, 0, status); - }); + } self.adv_info.remove(®_id); } else { info.tx_power = Some(tx_power.into()); info.expire_time = gen_expire_time_from_now(info.duration); - self.callbacks.get_by_id_mut(info.callback_id).map(|cb| { + if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) { cb.on_advertising_set_started(info.id, info.id, tx_power.into(), status); - }); + } } } else { // Not the first time. This means we are not able to report the failure through @@ -2000,10 +1998,8 @@ impl BtifGattAdvCallbacks for SoftwareRotationAdvertiseManagerImpl { info.enabled = false; // Push to the queue and let refresh_queue handle the disabled callback. self.adv_queue.push_back(reg_id); - } else { - if !info.enabled { - self.stop_current_advertising(); - } + } else if !info.enabled { + self.stop_current_advertising(); } } } else { @@ -2104,31 +2100,31 @@ mod tests { fn test_append_ad_data_multiple() { let mut bytes = Vec::::new(); - let payload = vec![0 as u8, 1, 2, 3, 4]; + let payload = vec![0_u8, 1, 2, 3, 4]; AdvertiseData::append_adv_data(&mut bytes, 100, &payload); AdvertiseData::append_adv_data(&mut bytes, 101, &[0]); - assert_eq!(bytes, vec![6 as u8, 100, 0, 1, 2, 3, 4, 2, 101, 0]); + assert_eq!(bytes, vec![6_u8, 100, 0, 1, 2, 3, 4, 2, 101, 0]); } #[test] fn test_append_service_uuids() { let mut bytes = Vec::::new(); let uuid_16 = Uuid::from_string("0000fef3-0000-1000-8000-00805f9b34fb").unwrap(); - let uuids = vec![uuid_16.clone()]; + let uuids = vec![uuid_16]; let exp_16: Vec = vec![3, 0x3, 0xf3, 0xfe]; AdvertiseData::append_service_uuids(&mut bytes, &uuids); assert_eq!(bytes, exp_16); let mut bytes = Vec::::new(); let uuid_32 = Uuid::from_string("00112233-0000-1000-8000-00805f9b34fb").unwrap(); - let uuids = vec![uuid_32.clone()]; + let uuids = vec![uuid_32]; let exp_32: Vec = vec![5, 0x5, 0x33, 0x22, 0x11, 0x0]; AdvertiseData::append_service_uuids(&mut bytes, &uuids); assert_eq!(bytes, exp_32); let mut bytes = Vec::::new(); let uuid_128 = Uuid::from_string("00010203-0405-0607-0809-0a0b0c0d0e0f").unwrap(); - let uuids = vec![uuid_128.clone()]; + let uuids = vec![uuid_128]; let exp_128: Vec = vec![ 17, 0x7, 0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0, ]; @@ -2224,7 +2220,7 @@ mod tests { #[test] fn test_append_manufacturer_data() { let mut bytes = Vec::::new(); - let manufacturer_data = HashMap::from([(0x0123 as u16, vec![0, 1, 2])]); + let manufacturer_data = HashMap::from([(0x0123_u16, vec![0, 1, 2])]); let exp_bytes: Vec = vec![6, 0xff, 0x23, 0x01, 0x0, 0x1, 0x2]; AdvertiseData::append_manufacturer_data(&mut bytes, &manufacturer_data); assert_eq!(bytes, exp_bytes); diff --git a/system/gd/rust/linux/stack/src/bluetooth_gatt.rs b/system/gd/rust/linux/stack/src/bluetooth_gatt.rs index c6f71119c30..d7f4a080f7b 100644 --- a/system/gd/rust/linux/stack/src/bluetooth_gatt.rs +++ b/system/gd/rust/linux/stack/src/bluetooth_gatt.rs @@ -94,10 +94,7 @@ impl ContextMap { } fn get_address_by_conn_id(&self, conn_id: i32) -> Option { - match self.connections.iter().find(|conn| conn.conn_id == conn_id) { - None => None, - Some(conn) => Some(conn.address), - } + self.connections.iter().find(|conn| conn.conn_id == conn_id).map(|conn| conn.address) } fn get_client_by_conn_id(&self, conn_id: i32) -> Option<&Client> { @@ -126,7 +123,7 @@ impl ContextMap { self.clients.push(Client { id: None, cbid, - uuid: uuid.clone(), + uuid: *uuid, is_congested: false, congestion_queue: vec![], }); @@ -165,14 +162,10 @@ impl ContextMap { } fn get_conn_id_from_address(&self, client_id: i32, address: &RawAddress) -> Option { - match self - .connections + self.connections .iter() .find(|conn| conn.client_id == client_id && conn.address == *address) - { - None => None, - Some(conn) => Some(conn.conn_id), - } + .map(|conn| conn.conn_id) } fn get_client_ids_from_address(&self, address: &RawAddress) -> Vec { @@ -254,7 +247,7 @@ impl ServerContextMap { fn get_mut_by_conn_id(&mut self, conn_id: i32) -> Option<&mut Server> { self.connections .iter() - .find_map(|conn| (conn.conn_id == conn_id).then(|| conn.server_id.clone())) + .find_map(|conn| (conn.conn_id == conn_id).then_some(conn.server_id)) .and_then(move |server_id| self.get_mut_by_server_id(server_id)) } @@ -268,7 +261,7 @@ impl ServerContextMap { self.servers.push(Server { id: None, cbid, - uuid: uuid.clone(), + uuid: *uuid, services: vec![], is_congested: false, congestion_queue: vec![], @@ -331,7 +324,7 @@ impl ServerContextMap { } fn get_address_from_conn_id(&self, conn_id: i32) -> Option { - self.connections.iter().find_map(|conn| (conn.conn_id == conn_id).then(|| conn.address)) + self.connections.iter().find_map(|conn| (conn.conn_id == conn_id).then_some(conn.address)) } fn add_service(&mut self, server_id: i32, service: BluetoothGattService) { @@ -341,8 +334,9 @@ impl ServerContextMap { } fn delete_service(&mut self, server_id: i32, handle: i32) { - self.get_mut_by_server_id(server_id) - .map(|s: &mut Server| s.services.retain(|service| service.instance_id != handle)); + if let Some(s) = self.get_mut_by_server_id(server_id) { + s.services.retain(|service| service.instance_id != handle) + } } fn add_request(&mut self, request_id: i32, handle: i32) { @@ -354,7 +348,9 @@ impl ServerContextMap { } fn get_request_handle_from_id(&self, request_id: i32) -> Option { - self.requests.iter().find_map(|request| (request.id == request_id).then(|| request.handle)) + self.requests + .iter() + .find_map(|request| (request.id == request_id).then_some(request.handle)) } } @@ -1154,42 +1150,32 @@ pub enum GattDbElementType { Descriptor = 4, } -impl Into for GattDbElementType { - fn into(self) -> i32 { - self.to_u8().unwrap_or(0).into() +impl From for i32 { + fn from(val: GattDbElementType) -> Self { + val.to_u8().unwrap_or(0).into() } } -#[derive(Debug, FromPrimitive, ToPrimitive, Copy, Clone)] +#[derive(Debug, Default, FromPrimitive, ToPrimitive, Copy, Clone)] #[repr(u8)] /// GATT write type. pub enum GattWriteType { Invalid = 0, WriteNoRsp = 1, + #[default] Write = 2, WritePrepare = 3, } -impl Default for GattWriteType { - fn default() -> Self { - GattWriteType::Write - } -} - -#[derive(Debug, FromPrimitive, ToPrimitive, Clone, PartialEq)] +#[derive(Debug, Default, FromPrimitive, ToPrimitive, Clone, PartialEq)] #[repr(u32)] /// Scan type configuration. pub enum ScanType { + #[default] Active = 0, Passive = 1, } -impl Default for ScanType { - fn default() -> Self { - ScanType::Active - } -} - /// Represents scanning configurations to be passed to `IBluetoothGatt::start_scan`. /// /// This configuration is general and supported on all Bluetooth hardware, irrelevant of the @@ -1221,7 +1207,7 @@ impl ScanSettings { return None; } }; - return Some((scan_type, interval, window)); + Some((scan_type, interval, window)) } } @@ -1614,13 +1600,7 @@ impl BluetoothGatt { .unwrap() .iter() .filter(|(_uuid, scanner)| scanner.callback_id == callback_id) - .filter_map(|(_uuid, scanner)| { - if let Some(scanner_id) = scanner.scanner_id { - Some(scanner_id) - } else { - None - } - }) + .filter_map(|(_uuid, scanner)| scanner.scanner_id) .collect(); // All scanners associated with the callback must be also unregistered. @@ -1677,7 +1657,7 @@ impl BluetoothGatt { } } self.set_scan_suspend_mode(SuspendMode::Suspended); - return BtStatus::Success; + BtStatus::Success } /// Exits suspend mode for LE Scan. @@ -1721,7 +1701,7 @@ impl BluetoothGatt { self.set_scan_suspend_mode(SuspendMode::Normal); - return BtStatus::Success; + BtStatus::Success } fn find_scanner_by_id<'a>( @@ -1803,8 +1783,10 @@ impl BluetoothGatt { // The address monitor handles are needed in stop_scan(). let addr_info: MsftAdvMonitorAddress = (&scan_filter.condition).into(); - if scanner.addr_handle_map.contains_key(&addr_info.bd_addr) { - scanner.addr_handle_map.insert(addr_info.bd_addr, Some(monitor_handle)); + if let std::collections::hash_map::Entry::Occupied(mut e) = + scanner.addr_handle_map.entry(addr_info.bd_addr) + { + e.insert(Some(monitor_handle)); log::debug!( "Added addr monitor {} and updated bd_addr={} to addr filter map", monitor_handle, @@ -2056,19 +2038,19 @@ impl ScannerInfo { } } -impl Into for &ScanFilterPattern { - fn into(self) -> MsftAdvMonitorPattern { +impl From<&ScanFilterPattern> for MsftAdvMonitorPattern { + fn from(val: &ScanFilterPattern) -> Self { MsftAdvMonitorPattern { - ad_type: self.ad_type, - start_byte: self.start_position, - pattern: self.content.clone(), + ad_type: val.ad_type, + start_byte: val.start_position, + pattern: val.content.clone(), } } } -impl Into> for &ScanFilterCondition { - fn into(self) -> Vec { - match self { +impl From<&ScanFilterCondition> for Vec { + fn from(val: &ScanFilterCondition) -> Self { + match val { ScanFilterCondition::Patterns(patterns) => { patterns.iter().map(|pattern| pattern.into()).collect() } @@ -2077,24 +2059,24 @@ impl Into> for &ScanFilterCondition { } } -impl Into for &ScanFilterAddress { - fn into(self) -> MsftAdvMonitorAddress { - MsftAdvMonitorAddress { addr_type: self.addr_type, bd_addr: self.bd_addr } +impl From<&ScanFilterAddress> for MsftAdvMonitorAddress { + fn from(val: &ScanFilterAddress) -> Self { + MsftAdvMonitorAddress { addr_type: val.addr_type, bd_addr: val.bd_addr } } } -impl Into for &ScanFilterCondition { - fn into(self) -> MsftAdvMonitorAddress { - match &self { +impl From<&ScanFilterCondition> for MsftAdvMonitorAddress { + fn from(val: &ScanFilterCondition) -> Self { + match &val { ScanFilterCondition::BluetoothAddress(addr_info) => addr_info.into(), _ => MsftAdvMonitorAddress { addr_type: 0, bd_addr: RawAddress::empty() }, } } } -impl Into for &ScanFilter { - fn into(self) -> MsftAdvMonitor { - let scan_filter_condition_type = match self.condition { +impl From<&ScanFilter> for MsftAdvMonitor { + fn from(val: &ScanFilter) -> Self { + let scan_filter_condition_type = match val.condition { ScanFilterCondition::Patterns(_) => { ScanFilterConditionType::MsftConditionTypePatterns as u8 } @@ -2104,13 +2086,13 @@ impl Into for &ScanFilter { _ => ScanFilterConditionType::MsftConditionTypeAll as u8, }; MsftAdvMonitor { - rssi_high_threshold: self.rssi_high_threshold.try_into().unwrap(), - rssi_low_threshold: self.rssi_low_threshold.try_into().unwrap(), - rssi_low_timeout: self.rssi_low_timeout.try_into().unwrap(), - rssi_sampling_period: self.rssi_sampling_period.try_into().unwrap(), + rssi_high_threshold: val.rssi_high_threshold.try_into().unwrap(), + rssi_low_threshold: val.rssi_low_threshold.try_into().unwrap(), + rssi_low_timeout: val.rssi_low_timeout.try_into().unwrap(), + rssi_sampling_period: val.rssi_sampling_period.try_into().unwrap(), condition_type: scan_filter_condition_type, - patterns: (&self.condition).into(), - addr_info: (&self.condition).into(), + patterns: (&val.condition).into(), + addr_info: (&val.condition).into(), } } } @@ -2226,7 +2208,7 @@ impl IBluetoothGatt for BluetoothGatt { } } - return self.add_monitor_and_update_scan(scanner_id, filter); + self.add_monitor_and_update_scan(scanner_id, filter) } fn stop_scan(&mut self, scanner_id: u8) -> BtStatus { @@ -2574,7 +2556,7 @@ impl IBluetoothGatt for BluetoothGatt { &value, ); - return GattWriteRequestStatus::Success; + GattWriteRequestStatus::Success } fn read_descriptor(&self, client_id: i32, addr: RawAddress, handle: i32, auth_req: i32) { @@ -2836,7 +2818,7 @@ impl IBluetoothGatt for BluetoothGatt { handle: handle as u16, offset: offset as u16, len, - auth_req: 0 as u8, + auth_req: 0_u8, }, }, ); @@ -2999,12 +2981,9 @@ impl BtifGattClientCallbacks for BluetoothGatt { match client { Some(c) => { let cbid = c.cbid; - self.context_map.get_callback_from_callback_id(cbid).and_then( - |cb: &mut GattClientCallback| { - cb.on_client_registered(status, client_id); - Some(()) - }, - ); + if let Some(cb) = self.context_map.get_callback_from_callback_id(cbid) { + cb.on_client_registered(status, client_id); + } } None => { warn!("Warning: Client not registered for UUID {}", DisplayUuid(&app_uuid)); @@ -3164,16 +3143,15 @@ impl BtifGattClientCallbacks for BluetoothGatt { let cbid = client.cbid; let mut congestion_queue: Vec<(RawAddress, GattStatus, i32)> = vec![]; client.congestion_queue.retain(|v| { - congestion_queue.push(v.clone()); + congestion_queue.push(*v); false }); - self.context_map.get_callback_from_callback_id(cbid).and_then( + self.context_map.get_callback_from_callback_id(cbid).map( |cb: &mut GattClientCallback| { for callback in congestion_queue.iter() { - cb.on_characteristic_write(callback.0.clone(), callback.1, callback.2); + cb.on_characteristic_write(callback.0, callback.1, callback.2); } - Some(()) }, ); } @@ -3447,10 +3425,7 @@ impl BtifGattServerCallbacks for BluetoothGatt { self.server_context_map.delete_service(server_id, handle); } - let cbid = self - .server_context_map - .get_by_server_id(server_id) - .and_then(|server| Some(server.cbid)); + let cbid = self.server_context_map.get_by_server_id(server_id).map(|server| server.cbid); if let Some(cbid) = cbid { if let Some(cb) = self.server_context_map.get_callback_from_callback_id(cbid).as_mut() { @@ -3601,7 +3576,7 @@ impl BtifGattServerCallbacks for BluetoothGatt { self.server_context_map.get_callback_from_callback_id(cbid).as_mut() { for callback in congestion_queue { - cb.on_notification_sent(callback.0.clone(), callback.1); + cb.on_notification_sent(callback.0, callback.1); } } } @@ -4346,10 +4321,7 @@ mod tests { match found { Some(c) => { let cbid = c.cbid; - map.callbacks - .get_by_id(cbid) - .and_then(|cb| Some(cb.get_object_id())) - .unwrap_or(String::new()) + map.callbacks.get_by_id(cbid).map(|cb| cb.get_object_id()).unwrap_or_default() } None => String::new(), } @@ -4366,10 +4338,7 @@ mod tests { match found { Some(c) => { let cbid = c.cbid; - map.callbacks - .get_by_id(cbid) - .and_then(|cb| Some(cb.get_object_id())) - .unwrap_or(String::new()) + map.callbacks.get_by_id(cbid).map(|cb| cb.get_object_id()).unwrap_or_default() } None => String::new(), } diff --git a/system/gd/rust/linux/stack/src/bluetooth_media.rs b/system/gd/rust/linux/stack/src/bluetooth_media.rs index fad90b5a227..3dc949e8927 100644 --- a/system/gd/rust/linux/stack/src/bluetooth_media.rs +++ b/system/gd/rust/linux/stack/src/bluetooth_media.rs @@ -561,15 +561,15 @@ impl BluetoothMedia { } fn is_profile_connected(&self, addr: &RawAddress, profile: &Profile) -> bool { - self.is_any_profile_connected(addr, &[profile.clone()]) + self.is_any_profile_connected(addr, &[*profile]) } fn is_any_profile_connected(&self, addr: &RawAddress, profiles: &[Profile]) -> bool { if let Some(connected_profiles) = self.connected_profiles.get(addr) { - return profiles.iter().any(|p| connected_profiles.contains(&p)); + return profiles.iter().any(|p| connected_profiles.contains(p)); } - return false; + false } fn add_connected_profile(&mut self, addr: RawAddress, profile: Profile) { @@ -578,7 +578,7 @@ impl BluetoothMedia { return; } - self.connected_profiles.entry(addr).or_insert_with(HashSet::new).insert(profile); + self.connected_profiles.entry(addr).or_default().insert(profile); self.notify_media_capability_updated(addr); } @@ -594,7 +594,7 @@ impl BluetoothMedia { return; } - self.connected_profiles.entry(addr).or_insert_with(HashSet::new).remove(&profile); + self.connected_profiles.entry(addr).or_default().remove(&profile); self.delay_volume_update.remove(&profile); if is_profile_critical && self.is_complete_profiles_required() { @@ -621,11 +621,11 @@ impl BluetoothMedia { } }; - match self.le_audio_groups.get_mut(&group_id) { + match self.le_audio_groups.get_mut(group_id) { Some(group) => { group.devices.remove(&addr); if group.devices.is_empty() { - self.le_audio_groups.remove(&group_id); + self.le_audio_groups.remove(group_id); } } None => { @@ -634,7 +634,6 @@ impl BluetoothMedia { DisplayAddress(&addr), group_id ); - return; } } } @@ -700,7 +699,7 @@ impl BluetoothMedia { if self.is_profile_enabled(profile).unwrap() { self.delay_enable_profiles.remove(profile); } else { - self.delay_enable_profiles.insert(profile.clone()); + self.delay_enable_profiles.insert(*profile); } } @@ -771,7 +770,7 @@ impl BluetoothMedia { pub fn dispatch_csis_callbacks(&mut self, cb: CsisClientCallbacks) { match cb { CsisClientCallbacks::ConnectionState(addr, state) => { - if !self.csis_states.get(&addr).is_none() + if self.csis_states.get(&addr).is_some() && state == *self.csis_states.get(&addr).unwrap() { return; @@ -836,7 +835,7 @@ impl BluetoothMedia { pub fn dispatch_vc_callbacks(&mut self, cb: VolumeControlCallbacks) { match cb { VolumeControlCallbacks::ConnectionState(state, addr) => { - if !self.vc_states.get(&addr).is_none() + if self.vc_states.get(&addr).is_some() && state == *self.vc_states.get(&addr).unwrap() { return; @@ -943,7 +942,7 @@ impl BluetoothMedia { info!("LeAudioClientCallbacks::Initialized: "); } LeAudioClientCallbacks::ConnectionState(state, addr) => { - if !self.le_audio_states.get(&addr).is_none() + if self.le_audio_states.get(&addr).is_some() && state == *self.le_audio_states.get(&addr).unwrap() { return; @@ -1013,12 +1012,11 @@ impl BluetoothMedia { self.le_audio_states.insert(addr, state); } BtLeAudioConnectionState::Disconnected => { - if self.le_audio_states.remove(&addr).is_some() { - if is_only_connected_member { - self.callbacks.lock().unwrap().for_all_callbacks(|callback| { - callback.on_lea_group_disconnected(group_id); - }); - } + if self.le_audio_states.remove(&addr).is_some() && is_only_connected_member + { + self.callbacks.lock().unwrap().for_all_callbacks(|callback| { + callback.on_lea_group_disconnected(group_id); + }); } // In anticipation that it could possibly never be connected. @@ -1030,7 +1028,7 @@ impl BluetoothMedia { } } LeAudioClientCallbacks::GroupStatus(group_id, status) => { - if !self.le_audio_groups.get(&group_id).is_none() + if self.le_audio_groups.get(&group_id).is_some() && status == self.le_audio_groups.get(&group_id).unwrap().status { return; @@ -1170,7 +1168,7 @@ impl BluetoothMedia { group_id, input_codec_conf, output_codec_conf, input_caps, output_caps); } LeAudioClientCallbacks::UnicastMonitorModeStatus(direction, status) => { - if !self.le_audio_unicast_monitor_mode_status.get(&direction.into()).is_none() + if self.le_audio_unicast_monitor_mode_status.get(&direction.into()).is_some() && status == *self .le_audio_unicast_monitor_mode_status @@ -1192,7 +1190,7 @@ impl BluetoothMedia { self.le_audio_unicast_monitor_mode_status.insert(direction.into(), status); } LeAudioClientCallbacks::GroupStreamStatus(group_id, status) => { - if !self.le_audio_groups.get(&group_id).is_none() + if self.le_audio_groups.get(&group_id).is_some() && status == self.le_audio_groups.get(&group_id).unwrap().stream_status { return; @@ -1215,7 +1213,7 @@ impl BluetoothMedia { pub fn dispatch_a2dp_callbacks(&mut self, cb: A2dpCallbacks) { match cb { A2dpCallbacks::ConnectionState(addr, state, error) => { - if !self.a2dp_states.get(&addr).is_none() + if self.a2dp_states.get(&addr).is_some() && state == *self.a2dp_states.get(&addr).unwrap() { return; @@ -1350,7 +1348,7 @@ impl BluetoothMedia { } AvrcpCallbacks::AvrcpAbsoluteVolumeUpdate(volume) => { for (addr, state) in self.device_states.lock().unwrap().iter() { - info!("[{}]: state {:?}", DisplayAddress(&addr), state); + info!("[{}]: state {:?}", DisplayAddress(addr), state); match state { DeviceConnectionStates::ConnectingBeforeRetry | DeviceConnectionStates::ConnectingAfterRetry @@ -1417,7 +1415,7 @@ impl BluetoothMedia { pub fn dispatch_hfp_callbacks(&mut self, cb: HfpCallbacks) { match cb { HfpCallbacks::ConnectionState(state, addr) => { - if !self.hfp_states.get(&addr).is_none() + if self.hfp_states.get(&addr).is_some() && state == *self.hfp_states.get(&addr).unwrap() { return; @@ -1436,9 +1434,7 @@ impl BluetoothMedia { info!("[{}]: hfp slc connected.", DisplayAddress(&addr)); // The device may not support codec-negotiation, // in which case we shall assume it supports CVSD at this point. - if !self.hfp_cap.contains_key(&addr) { - self.hfp_cap.insert(addr, HfpCodecFormat::CVSD); - } + self.hfp_cap.entry(addr).or_insert(HfpCodecFormat::CVSD); self.add_connected_profile(addr, Profile::Hfp); // Connect SCO if phone operations are enabled and an active call exists. @@ -1767,9 +1763,9 @@ impl BluetoothMedia { self.simple_at_response(false, addr); return; } - let number = if number == "" { + let number = if number.is_empty() { self.last_dialing_number.clone() - } else if number.starts_with(">") { + } else if number.starts_with('>') { self.memory_dialing_number.clone() } else { Some(number) @@ -1909,19 +1905,19 @@ impl BluetoothMedia { fn uhid_destroy(&mut self, addr: &RawAddress) { if let Some(uhid) = self.uhid.get_mut(addr) { - debug!("[{}]: UHID destroy", DisplayAddress(&addr)); + debug!("[{}]: UHID destroy", DisplayAddress(addr)); match uhid.handle.destroy() { Err(e) => log::error!( "[{}]: UHID destroy: Fail to destroy uhid {}", - DisplayAddress(&addr), + DisplayAddress(addr), e ), Ok(_) => (), }; self.uhid.remove(addr); - self.notify_telephony_event(&addr, TelephonyEvent::UHidDestroy); + self.notify_telephony_event(addr, TelephonyEvent::UHidDestroy); } else { - debug!("[{}]: UHID destroy: not a UHID device", DisplayAddress(&addr)); + debug!("[{}]: UHID destroy: not a UHID device", DisplayAddress(addr)); } } @@ -1932,7 +1928,7 @@ impl BluetoothMedia { if let Some(uhid) = self.uhid.get_mut(addr) { info!( "[{}]: UHID: Send telephony hid input report. hook_switch({}), mute({}), drop({})", - DisplayAddress(&addr), + DisplayAddress(addr), (data & UHID_INPUT_HOOK_SWITCH) != 0, (data & UHID_INPUT_PHONE_MUTE) != 0, (data & UHID_INPUT_DROP) != 0, @@ -1940,7 +1936,7 @@ impl BluetoothMedia { match uhid.handle.send_input(data) { Err(e) => log::error!( "[{}]: UHID: Fail to send hid input report. err:{}", - DisplayAddress(&addr), + DisplayAddress(addr), e ), Ok(_) => (), @@ -1963,7 +1959,7 @@ impl BluetoothMedia { if uhid.muted { data |= UHID_INPUT_PHONE_MUTE; } - self.uhid_send_input_event_report(&addr, data); + self.uhid_send_input_event_report(addr, data); }; } fn uhid_send_phone_mute_input_report(&mut self, addr: &RawAddress, muted: bool) { @@ -1979,13 +1975,13 @@ impl BluetoothMedia { } info!( "[{}]: UHID: Send phone_mute({}) hid input report. hook-switch({})", - DisplayAddress(&addr), + DisplayAddress(addr), muted, call_active ); if muted { data |= UHID_INPUT_PHONE_MUTE; - self.uhid_send_input_event_report(&addr, data); + self.uhid_send_input_event_report(addr, data); } else { // We follow the same pattern as the USB headset, which sends an // additional phone mute=1 event when unmuting the microphone. @@ -1993,9 +1989,9 @@ impl BluetoothMedia { // mute=0 and treat the phone mute=1 event as a toggle rather than // an on off control. data |= UHID_INPUT_PHONE_MUTE; - self.uhid_send_input_event_report(&addr, data); + self.uhid_send_input_event_report(addr, data); data &= !UHID_INPUT_PHONE_MUTE; - self.uhid_send_input_event_report(&addr, data); + self.uhid_send_input_event_report(addr, data); } }; } @@ -2232,7 +2228,7 @@ impl BluetoothMedia { fn is_bonded(&self, addr: &RawAddress) -> bool { match &self.adapter { Some(adapter) => { - BtBondState::Bonded == adapter.lock().unwrap().get_bond_state_by_addr(&addr) + BtBondState::Bonded == adapter.lock().unwrap().get_bond_state_by_addr(addr) } _ => false, } @@ -2287,7 +2283,7 @@ impl BluetoothMedia { let available_profiles = self.adapter_get_classic_audio_profiles(addr); let connected_profiles = self.connected_profiles.get(&addr).unwrap(); let missing_profiles = - available_profiles.difference(&connected_profiles).cloned().collect::>(); + available_profiles.difference(connected_profiles).cloned().collect::>(); // Update device states if states.get(&addr).is_none() { @@ -2319,19 +2315,17 @@ impl BluetoothMedia { states.insert(addr, DeviceConnectionStates::WaitingConnection); } - } else { - if missing_profiles.is_empty() - || missing_profiles == HashSet::from([Profile::AvrcpController]) - { - info!( - "[{}]: Fully connected, available profiles: {:?}, connected profiles: {:?}.", - DisplayAddress(&addr), - available_profiles, - connected_profiles - ); + } else if missing_profiles.is_empty() + || missing_profiles == HashSet::from([Profile::AvrcpController]) + { + info!( + "[{}]: Fully connected, available profiles: {:?}, connected profiles: {:?}.", + DisplayAddress(&addr), + available_profiles, + connected_profiles + ); - states.insert(addr, DeviceConnectionStates::FullyConnected); - } + states.insert(addr, DeviceConnectionStates::FullyConnected); } } @@ -2465,7 +2459,7 @@ impl BluetoothMedia { .get_remote_uuids(device) .into_iter() .filter_map(|u| UuidHelper::is_known_profile(&u)) - .filter(|u| MEDIA_LE_AUDIO_PROFILES.contains(&u)) + .filter(|u| MEDIA_LE_AUDIO_PROFILES.contains(u)) .collect() } else { HashSet::new() @@ -2481,7 +2475,7 @@ impl BluetoothMedia { .get_remote_uuids(device) .into_iter() .filter_map(|u| UuidHelper::is_known_profile(&u)) - .filter(|u| MEDIA_CLASSIC_AUDIO_PROFILES.contains(&u)) + .filter(|u| MEDIA_CLASSIC_AUDIO_PROFILES.contains(u)) .collect() } else { HashSet::new() @@ -2562,8 +2556,8 @@ impl BluetoothMedia { devices .iter() .filter(|d| { - self.is_any_profile_connected(&d.address, &MEDIA_CLASSIC_AUDIO_PROFILES) - || self.is_any_profile_connected(&d.address, &MEDIA_LE_AUDIO_PROFILES) + self.is_any_profile_connected(&d.address, MEDIA_CLASSIC_AUDIO_PROFILES) + || self.is_any_profile_connected(&d.address, MEDIA_LE_AUDIO_PROFILES) }) .cloned() .collect() @@ -2989,7 +2983,7 @@ impl BluetoothMedia { } }; - return interop_insert_call_when_sco_start(address); + interop_insert_call_when_sco_start(address) } // Places an active call into the call list and triggers a headset update (+CIEV). // Preconditions: @@ -3391,11 +3385,11 @@ impl IBluetoothMedia for BluetoothMedia { available_profiles ); - let connected_profiles = self.connected_profiles.entry(addr).or_insert_with(HashSet::new); + let connected_profiles = self.connected_profiles.entry(addr).or_default(); // Sort here so the order of connection is always consistent let missing_profiles = - available_profiles.difference(&connected_profiles).sorted().collect::>(); + available_profiles.difference(connected_profiles).sorted().collect::>(); // Connect the profiles one-by-one so it won't stuck at the lower layer. // Therefore, just connect to one profile for now. @@ -3520,7 +3514,7 @@ impl IBluetoothMedia for BluetoothMedia { if is_connect { let mut tasks = self.fallback_tasks.lock().unwrap(); let mut states = self.device_states.lock().unwrap(); - if !tasks.contains_key(&addr) { + if let std::collections::hash_map::Entry::Vacant(e) = tasks.entry(addr) { states.insert(addr, DeviceConnectionStates::Initiating); let fallback_tasks = self.fallback_tasks.clone(); @@ -3539,7 +3533,7 @@ impl IBluetoothMedia for BluetoothMedia { fallback_tasks.lock().unwrap().remove(&addr); } }); - tasks.insert(addr, Some((task, now_ts))); + e.insert(Some((task, now_ts))); } } } @@ -3766,9 +3760,9 @@ impl IBluetoothMedia for BluetoothMedia { let config = vec![A2dpCodecConfig { codec_type: codec_type as i32, codec_priority: A2dpCodecPriority::Highest as i32, - sample_rate: sample_rate.bits() as i32, - bits_per_sample: bits_per_sample.bits() as i32, - channel_mode: channel_mode.bits() as i32, + sample_rate: sample_rate.bits(), + bits_per_sample: bits_per_sample.bits(), + channel_mode: channel_mode.bits(), ..Default::default() }]; @@ -4120,7 +4114,7 @@ impl IBluetoothTelephony for BluetoothMedia { } fn set_signal_strength(&mut self, signal_strength: i32) -> bool { - if signal_strength < 0 || signal_strength > 5 { + if !(0..=5).contains(&signal_strength) { warn!("Invalid signal strength, got {}, want 0 to 5", signal_strength); return false; } @@ -4135,7 +4129,7 @@ impl IBluetoothTelephony for BluetoothMedia { } fn set_battery_level(&mut self, battery_level: i32) -> bool { - if battery_level < 0 || battery_level > 5 { + if !(0..=5).contains(&battery_level) { warn!("Invalid battery level, got {}, want 0 to 5", battery_level); return false; } @@ -4204,7 +4198,7 @@ impl IBluetoothTelephony for BluetoothMedia { warn!("Unexpected incoming_call dbus command. mps_qualification_enabled does not enabled."); return false; } - return self.incoming_call_impl(number); + self.incoming_call_impl(number) } fn dialing_call(&mut self, number: String) -> bool { @@ -4212,7 +4206,7 @@ impl IBluetoothTelephony for BluetoothMedia { warn!("Unexpected incoming_call dbus command. mps_qualification_enabled does not enabled."); return false; } - return self.dialing_call_impl(number, None); + self.dialing_call_impl(number, None) } fn answer_call(&mut self) -> bool { @@ -4222,7 +4216,7 @@ impl IBluetoothTelephony for BluetoothMedia { ); return false; } - return self.answer_call_impl(); + self.answer_call_impl() } fn hangup_call(&mut self) -> bool { @@ -4232,7 +4226,7 @@ impl IBluetoothTelephony for BluetoothMedia { ); return false; } - return self.hangup_call_impl(); + self.hangup_call_impl() } fn set_memory_call(&mut self, number: Option) -> bool { @@ -4260,7 +4254,7 @@ impl IBluetoothTelephony for BluetoothMedia { ); return false; } - return self.release_held_impl(None); + self.release_held_impl(None) } fn release_active_accept_held(&mut self) -> bool { @@ -4268,7 +4262,7 @@ impl IBluetoothTelephony for BluetoothMedia { warn!("Unexpected release_active_accept_held dbus command. mps_qualification_enabled does not enabled."); return false; } - return self.release_active_accept_held_impl(None); + self.release_active_accept_held_impl(None) } fn hold_active_accept_held(&mut self) -> bool { @@ -4276,7 +4270,7 @@ impl IBluetoothTelephony for BluetoothMedia { warn!("Unexpected hold_active_accept_held dbus command. mps_qualification_enabled does not enabled."); return false; } - return self.hold_active_accept_held_impl(None); + self.hold_active_accept_held_impl(None) } fn audio_connect(&mut self, address: RawAddress) -> bool { diff --git a/system/gd/rust/linux/stack/src/dis.rs b/system/gd/rust/linux/stack/src/dis.rs index 14d09d09ad7..bc9f2902f3a 100644 --- a/system/gd/rust/linux/stack/src/dis.rs +++ b/system/gd/rust/linux/stack/src/dis.rs @@ -63,9 +63,7 @@ impl DeviceInformation { // Construct and add Device Information service. let mut service = BluetoothGattService::new( - UuidHelper::get_profile_uuid(&Profile::Dis) - .expect("DIS uuid mapping missing") - .clone(), + *UuidHelper::get_profile_uuid(&Profile::Dis).expect("DIS uuid mapping missing"), /*instance_id=*/ 0, GattDbElementType::PrimaryService.into(), ); diff --git a/system/gd/rust/linux/stack/src/socket_manager.rs b/system/gd/rust/linux/stack/src/socket_manager.rs index d9ae68d7112..a56a72f9a30 100644 --- a/system/gd/rust/linux/stack/src/socket_manager.rs +++ b/system/gd/rust/linux/stack/src/socket_manager.rs @@ -114,9 +114,9 @@ impl BluetoothServerSocket { sock_type: SocketType::Rfcomm, flags, psm: None, - channel: channel, - name: name, - uuid: uuid, + channel, + name, + uuid, } } @@ -145,7 +145,7 @@ impl BluetoothServerSocket { sock.id = self.id; sock.sock_type = self.sock_type.clone(); sock.flags = self.flags; - sock.uuid = self.uuid.clone(); + sock.uuid = self.uuid; // Data from connection. sock.remote_device = BluetoothDevice::new(conn.addr, "".into()); @@ -170,7 +170,7 @@ impl fmt::Display for BluetoothServerSocket { (Some(psm), Some(cn)) => format!("psm {} | cn {}", psm, cn), (None, Some(cn)) => format!("cn {}", cn), (Some(psm), None) => format!("psm {}", psm), - (None, None) => format!("none"), + (None, None) => "none".to_string(), }, self.sock_type, self.name.as_ref().unwrap_or(&String::new()), @@ -628,7 +628,7 @@ impl BluetoothSocketManager { let id = self.next_socket_id(); socket_info.id = id; let (runner_tx, runner_rx) = channel::(10); - let uuid = socket_info.uuid.clone(); + let uuid = socket_info.uuid; // Push a listening task to local runtime to wait for device to // start accepting or get closed. @@ -644,7 +644,7 @@ impl BluetoothSocketManager { }; // We only send socket ready after we've read the channel out. - let listen_status = status.clone(); + let listen_status = status; let joinhandle = self.runtime.spawn(async move { BluetoothSocketManager::listening_task( cbid, @@ -768,7 +768,7 @@ impl BluetoothSocketManager { let connection_timeout = Duration::from_millis(CONNECT_COMPLETE_TIMEOUT_MS); // Wait for stream to be readable, then read channel. This is the first thing that must // happen in the listening channel. If this fails, close the channel. - let mut channel_bytes = [0 as u8; 4]; + let mut channel_bytes = [0_u8; 4]; let mut status = Self::wait_and_read_stream(connection_timeout, &stream, &mut channel_bytes).await; let channel = i32::from_ne_bytes(channel_bytes); @@ -808,7 +808,7 @@ impl BluetoothSocketManager { }; // Notify via callbacks that this socket is ready to be listened to since we have the // channel available now. - let (forwarded_socket, forwarded_status) = (socket_info.clone(), listen_status.clone()); + let (forwarded_socket, forwarded_status) = (socket_info.clone(), listen_status); let _ = rpc_tx .send(Message::SocketManagerActions(SocketActions::OnIncomingSocketReady( cbid, @@ -945,7 +945,7 @@ impl BluetoothSocketManager { // If we returned an error for the above socket, then the recv failed. // Just continue this loop. - if !sock.is_ok() { + if sock.is_err() { continue; } @@ -1036,11 +1036,9 @@ impl BluetoothSocketManager { if n != buf.len() { return BtStatus::SocketError; } - return BtStatus::Success; - } - _ => { - return BtStatus::SocketError; + BtStatus::Success } + _ => BtStatus::SocketError, } } @@ -1074,7 +1072,7 @@ impl BluetoothSocketManager { }; // Wait for stream to be readable, then read channel - let mut channel_bytes = [0 as u8; 4]; + let mut channel_bytes = [0_u8; 4]; let mut status = Self::wait_and_read_stream(connection_timeout, &stream, &mut channel_bytes).await; if i32::from_ne_bytes(channel_bytes) <= 0 { @@ -1115,10 +1113,7 @@ impl BluetoothSocketManager { let _ = tx .send(Message::SocketManagerActions( SocketActions::OnOutgoingConnectionResult( - cbid, - socket_id, - status.clone(), - None, + cbid, socket_id, status, None, ), )) .await; @@ -1134,7 +1129,7 @@ impl BluetoothSocketManager { SocketActions::OnOutgoingConnectionResult( cbid, socket_id, - status.clone(), + status, Some(sock), ), )) @@ -1205,7 +1200,6 @@ impl BluetoothSocketManager { let forbidden_sockets = self .listening .values() - .into_iter() .flatten() .filter(|sock| { sock.uuid @@ -1469,10 +1463,7 @@ impl IBluetoothSocketManager for BluetoothSocketManager { Some(v) => { if let Some(found) = v.iter().find(|item| item.socket_id == id) { let tx = found.tx.clone(); - let timeout_duration = match timeout_ms { - Some(t) => Some(Duration::from_millis(t.into())), - None => None, - }; + let timeout_duration = timeout_ms.map(|t| Duration::from_millis(t.into())); self.runtime.spawn(async move { let _ = tx.send(SocketRunnerActions::AcceptTimeout(id, timeout_duration)).await; diff --git a/system/gd/rust/linux/stack/src/suspend.rs b/system/gd/rust/linux/stack/src/suspend.rs index fa0a39e8b48..04902c588c3 100644 --- a/system/gd/rust/linux/stack/src/suspend.rs +++ b/system/gd/rust/linux/stack/src/suspend.rs @@ -285,7 +285,7 @@ impl ISuspend for Suspend { fn resume(&mut self) -> bool { // Suspend is not ready (e.g. aborted early), delay cleanup after SuspendReady. - if self.suspend_state.lock().unwrap().suspend_expected == true { + if self.suspend_state.lock().unwrap().suspend_expected { log::error!("Suspend is expected but not ready, abort resume."); return false; } diff --git a/system/gd/rust/linux/stack/src/uuid.rs b/system/gd/rust/linux/stack/src/uuid.rs index 8b56aee0386..ba9ccc40d6c 100644 --- a/system/gd/rust/linux/stack/src/uuid.rs +++ b/system/gd/rust/linux/stack/src/uuid.rs @@ -154,7 +154,7 @@ lazy_static! { lazy_static! { static ref PROFILES_UUIDS: HashMap = - PROFILES.iter().map(|(k, v)| (v.clone(), k.clone())).collect(); + PROFILES.iter().map(|(k, v)| (*v, *k)).collect(); } impl UuidHelper { @@ -187,7 +187,7 @@ impl UuidHelper { /// string that shows the service name. Else just format the uuid. pub fn known_uuid_to_string(uuid: &Uuid) -> String { if let Some(p) = Self::is_known_profile(uuid) { - format!("{}: {:?}", uuid.to_string(), p) + format!("{}: {:?}", uuid, p) } else { uuid.to_string() } diff --git a/system/gd/rust/linux/utils/src/at_command_parser.rs b/system/gd/rust/linux/utils/src/at_command_parser.rs index e9a22b66bae..225f1861a1a 100644 --- a/system/gd/rust/linux/utils/src/at_command_parser.rs +++ b/system/gd/rust/linux/utils/src/at_command_parser.rs @@ -63,8 +63,8 @@ const AT_COMMAND_ARG_DELIMITER: &str = ","; pub fn parse_at_command_data(at_string: String) -> Result { // All AT commands should be of the form AT+ but may be passed around as + or // . We remove those here for convenience. - let clean_at_string = at_string.strip_prefix("+").unwrap_or(&at_string); - let clean_at_string = clean_at_string.strip_prefix("AT+").unwrap_or(&clean_at_string); + let clean_at_string = at_string.strip_prefix('+').unwrap_or(&at_string); + let clean_at_string = clean_at_string.strip_prefix("AT+").unwrap_or(clean_at_string); if clean_at_string.is_empty() { return Err("Cannot parse empty AT command".to_string()); } @@ -92,7 +92,7 @@ pub fn parse_at_command_data(at_string: String) -> Result { }; let raw_args = match command_parts.next() { Some(arg_string) => { - if arg_string == "" { + if arg_string.is_empty() { None } else { Some( @@ -113,11 +113,11 @@ pub fn parse_at_command_data(at_string: String) -> Result { }; Ok(AtCommand { raw: at_string.to_string(), - at_type: at_type, + at_type, command: command.to_string(), - raw_args: raw_args, - vendor: vendor, - data: data, + raw_args, + vendor, + data, }) } @@ -190,7 +190,7 @@ fn parse_at_command_type(command: String) -> AtCommandType { if command.contains(AT_COMMAND_DELIMITER_SET) { return AtCommandType::Set; } - return AtCommandType::Execute; + AtCommandType::Execute } // Format: @@ -419,19 +419,19 @@ mod tests { fn test_calculate_battery_percent() { // Non-battery command let at_command = parse_at_command_data("AT+CMD".to_string()); - assert!(!at_command.is_err()); + assert!(at_command.is_ok()); let battery_level = calculate_battery_percent(at_command.unwrap()); assert!(battery_level.is_err()); // Apple - no battery let at_command = parse_at_command_data("AT+IPHONEACCEV=1,2,3".to_string()); - assert!(!at_command.is_err()); + assert!(at_command.is_ok()); let battery_level = calculate_battery_percent(at_command.unwrap()); assert!(battery_level.is_err()); // Apple let at_command = parse_at_command_data("AT+IPHONEACCEV=1,1,2".to_string()); - assert!(!at_command.is_err()); + assert!(at_command.is_ok()); let battery_level = calculate_battery_percent(at_command.unwrap()).unwrap(); assert_eq!(battery_level, 30); @@ -441,7 +441,7 @@ mod tests { // Plantronics let at_command = parse_at_command_data("AT+XEVENT=BATTERY,5,11,10,0".to_string()); - assert!(!at_command.is_err()); + assert!(at_command.is_ok()); let battery_level = calculate_battery_percent(at_command.unwrap()).unwrap(); assert_eq!(battery_level, 50); } diff --git a/system/gd/rust/linux/utils/src/cod.rs b/system/gd/rust/linux/utils/src/cod.rs index ac3473b97cb..35cf6a19437 100644 --- a/system/gd/rust/linux/utils/src/cod.rs +++ b/system/gd/rust/linux/utils/src/cod.rs @@ -31,11 +31,11 @@ mod tests { let combo_joystick_cod = 0x05c4; let mouse_cod = 0x0580; - assert_eq!(is_cod_hid_keyboard(keyboard_gamepad_cod), true); - assert_eq!(is_cod_hid_combo(keyboard_gamepad_cod), false); - assert_eq!(is_cod_hid_keyboard(combo_joystick_cod), false); - assert_eq!(is_cod_hid_combo(combo_joystick_cod), true); - assert_eq!(is_cod_hid_keyboard(mouse_cod), false); - assert_eq!(is_cod_hid_combo(mouse_cod), false); + assert!(is_cod_hid_keyboard(keyboard_gamepad_cod)); + assert!(!is_cod_hid_combo(keyboard_gamepad_cod)); + assert!(!is_cod_hid_keyboard(combo_joystick_cod)); + assert!(is_cod_hid_combo(combo_joystick_cod)); + assert!(!is_cod_hid_keyboard(mouse_cod)); + assert!(!is_cod_hid_combo(mouse_cod)); } } diff --git a/system/gd/rust/linux/utils/src/socket.rs b/system/gd/rust/linux/utils/src/socket.rs index 5cd9e5ed0ee..57e1bd3f075 100644 --- a/system/gd/rust/linux/utils/src/socket.rs +++ b/system/gd/rust/linux/utils/src/socket.rs @@ -269,9 +269,15 @@ impl Drop for BtSocket { } } +impl Default for BtSocket { + fn default() -> Self { + BtSocket { sock_fd: -1, channel_type: HciChannels::Unbound } + } +} + impl BtSocket { pub fn new() -> Self { - BtSocket { sock_fd: -1, channel_type: HciChannels::Unbound } + Default::default() } /// Is the current file descriptor valid? @@ -310,11 +316,11 @@ impl BtSocket { hci_channel: channel.into(), }; - return libc::bind( + libc::bind( self.sock_fd, (&addr as *const SockAddrHci) as *const libc::sockaddr, mem::size_of::() as u32, - ); + ) } } @@ -379,7 +385,7 @@ impl BtSocket { index: u16::from_le_bytes(index_arr.try_into().unwrap()), len: u16::from_le_bytes(len_arr.try_into().unwrap()), data: match data_size { - x if x > 0 => data_arr[..x].iter().map(|x| *x).collect::>(), + x if x > 0 => data_arr[..x].to_vec(), _ => Vec::new(), }, }) @@ -438,7 +444,7 @@ mod tests { packet.len = packet.data.len().try_into().unwrap_or(0); let event = packet.try_into(); - assert_eq!(true, event.is_ok(), "Packet doesn't parse into event."); + assert!(event.is_ok(), "Packet doesn't parse into event."); if let Ok(ev) = event { if let MgmtEvent::CommandComplete { opcode, status, response } = ev { assert_eq!(opcode, 0x3); diff --git a/system/gd/rust/linux/utils/src/uhid.rs b/system/gd/rust/linux/utils/src/uhid.rs index c15cafb8afb..8a93b9bb6c9 100644 --- a/system/gd/rust/linux/utils/src/uhid.rs +++ b/system/gd/rust/linux/utils/src/uhid.rs @@ -30,6 +30,7 @@ const RDESC: [u8; 34] = [ 0xc0, // END_COLLECTION ]; +#[derive(Default)] pub struct UHid { /// Open UHID objects. devices: Vec>, @@ -44,7 +45,7 @@ impl Drop for UHid { impl UHid { /// Create a new UHid struct that holds a vector of uhid objects. pub fn new() -> Self { - UHid { devices: Vec::>::new() } + Default::default() } /// Initialize a uhid device with kernel. diff --git a/system/gd/rust/linux/utils/src/uinput.rs b/system/gd/rust/linux/utils/src/uinput.rs index c8d7c50cae9..c129c920453 100644 --- a/system/gd/rust/linux/utils/src/uinput.rs +++ b/system/gd/rust/linux/utils/src/uinput.rs @@ -236,12 +236,8 @@ impl UInputDev { code: libc::c_ushort, value: libc::c_int, ) -> i32 { - let mut event = UInputEvent { - time: libc::timeval { tv_sec: 0, tv_usec: 0 }, - event_type: event_type, - code: code, - value: value, - }; + let mut event = + UInputEvent { time: libc::timeval { tv_sec: 0, tv_usec: 0 }, event_type, code, value }; unsafe { libc::write( @@ -295,6 +291,12 @@ impl Drop for UInput { } } +impl Default for UInput { + fn default() -> Self { + Self { devices: Vec::::new(), active_device: String::from("00:00:00:00:00:00") } + } +} + impl UInput { fn get_device(&mut self, addr: String) -> Option<&mut UInputDev> { for device in self.devices.iter_mut() { @@ -307,10 +309,7 @@ impl UInput { /// Create a new UInput struct that holds a vector of uinput objects. pub fn new() -> Self { - UInput { - devices: Vec::::new(), - active_device: String::from("00:00:00:00:00:00"), - } + Default::default() } /// Initialize a uinput device with kernel. @@ -350,7 +349,7 @@ impl UInput { /// Send key event to the active uinput. pub fn send_key(&mut self, key: u8, value: u8) -> Result<(), String> { match self.active_device.as_str() { - "00:00:00:00:00:00" => Err(format!("Active device is not specified")), + "00:00:00:00:00:00" => Err("Active device is not specified".to_string()), _ => match self.get_device(self.active_device.clone()) { Some(device) => device.send_key(key, value), None => Err(format!("uinput: {} is not initialized", self.active_device)), diff --git a/system/gd/rust/topshim/build.rs b/system/gd/rust/topshim/build.rs index ad646e085e6..71930042926 100644 --- a/system/gd/rust/topshim/build.rs +++ b/system/gd/rust/topshim/build.rs @@ -16,7 +16,7 @@ fn main() { .collect::>(); let search_root = env::var("CXX_ROOT_PATH").unwrap(); - let paths = vec![ + let paths = [ "/system/", "/system/btcore", "/system/include", @@ -38,7 +38,7 @@ fn main() { Ok(should_rebuild) => should_rebuild != "no", }; if topshim_should_rebuild { - println!("cargo:rerun-if-changed={}{}", search_root, "/system/"); + println!("cargo:rerun-if-changed={}/system/", search_root); } // "-x" and "c++" must be separate due to a bug diff --git a/system/gd/rust/topshim/tests/bdaddr.rs b/system/gd/rust/topshim/tests/bdaddr.rs index 44220eeea1e..9c2b209adad 100644 --- a/system/gd/rust/topshim/tests/bdaddr.rs +++ b/system/gd/rust/topshim/tests/bdaddr.rs @@ -25,14 +25,14 @@ mod tests { #[test] fn from_bytes_invalid() { - assert!(RawAddress::from_bytes(&vec![]).is_none()); - assert!(RawAddress::from_bytes(&vec![1, 2, 3, 4, 5]).is_none()); - assert!(RawAddress::from_bytes(&vec![1, 2, 3, 4, 5, 6, 7]).is_none()); + assert!(RawAddress::from_bytes(&[]).is_none()); + assert!(RawAddress::from_bytes(&[1, 2, 3, 4, 5]).is_none()); + assert!(RawAddress::from_bytes(&[1, 2, 3, 4, 5, 6, 7]).is_none()); } #[test] fn from_bytes_valid() { - let addr = RawAddress::from_bytes(&vec![1, 2, 3, 4, 5, 6]); + let addr = RawAddress::from_bytes(&[1, 2, 3, 4, 5, 6]); assert!(addr.is_some()); assert_eq!([1, 2, 3, 4, 5, 6], addr.unwrap().to_byte_arr()); } -- GitLab From 39bd62f6bb433f6e366fe55d8c4ddfdd539d0d16 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Tue, 11 Jun 2024 07:20:59 +0000 Subject: [PATCH 0028/1446] floss: notify hfp/a2dp audio status via forwarded fd This adds a parameter to |start/stop_x| so that the audio server can poll on the file descriptor for status update for faster transition. Bug: 343885745 Flag: EXEMPT floss-only Test: m Bluetooth Change-Id: Iac311e1b96bca68bb0a2533c80cc6120bfda3ea5 --- floss/pandora/floss/media_client.py | 26 +++--- system/gd/rust/linux/client/src/dbus_iface.rs | 8 +- .../service/src/iface_bluetooth_media.rs | 8 +- .../rust/linux/stack/src/bluetooth_media.rs | 81 +++++++++++++++++-- 4 files changed, 102 insertions(+), 21 deletions(-) diff --git a/floss/pandora/floss/media_client.py b/floss/pandora/floss/media_client.py index 83dbe1e2c4c..fdfa032e560 100644 --- a/floss/pandora/floss/media_client.py +++ b/floss/pandora/floss/media_client.py @@ -410,13 +410,16 @@ class FlossMediaClient(BluetoothMediaCallbacks): return True @utils.glib_call(False) - def start_audio_request(self): + def start_audio_request(self, connection_listener): """Starts audio request. + Args: + connection_listener: The file descriptor to write 1 (u8) on audio connection. + Returns: True on success, False otherwise. """ - self.proxy().StartAudioRequest() + self.proxy().StartAudioRequest(connection_listener) return True @utils.glib_call(None) @@ -432,28 +435,32 @@ class FlossMediaClient(BluetoothMediaCallbacks): return self.proxy().GetA2dpAudioStarted(address) @utils.glib_call(False) - def stop_audio_request(self): + def stop_audio_request(self, connection_listener): """Stops audio request. + Args: + connection_listener: The file descriptor to write 0 (u8) on audio connection. + Returns: True on success, False otherwise. """ - self.proxy().StopAudioRequest() + self.proxy().StopAudioRequest(connection_listener) return True @utils.glib_call(False) - def start_sco_call(self, address, sco_offload, force_cvsd): + def start_sco_call(self, address, sco_offload, disabled_codecs, connection_listener): """Starts the SCO call. Args: address: Device address to make SCO call. sco_offload: Whether SCO offload is enabled. - force_cvsd: True to force the stack to use CVSD even if mSBC is supported. + disabled_codecs: The disabled codecs in bitmask form. CVSD=1, MSBC=2, LC3=4. + connection_listener: The file descriptor to write the codec id on audio connection. Returns: True on success, False otherwise. """ - self.proxy().StartScoCall(address, sco_offload, force_cvsd) + self.proxy().StartScoCall(address, sco_offload, disabled_codecs, connection_listener) return True @utils.glib_call(None) @@ -470,16 +477,17 @@ class FlossMediaClient(BluetoothMediaCallbacks): return self.proxy().GetHfpAudioStarted(address) @utils.glib_call(False) - def stop_sco_call(self, address): + def stop_sco_call(self, address, connection_listener): """Stops the SCO call. Args: address: Device address to stop SCO call. + connection_listener: The file descriptor to write 0 (u8) on audio disconnection. Returns: True on success, False otherwise. """ - self.proxy().StopScoCall(address) + self.proxy().StopScoCall(address, connection_listener) return True @utils.glib_call(None) diff --git a/system/gd/rust/linux/client/src/dbus_iface.rs b/system/gd/rust/linux/client/src/dbus_iface.rs index e4c82bb5ea0..144f5693070 100644 --- a/system/gd/rust/linux/client/src/dbus_iface.rs +++ b/system/gd/rust/linux/client/src/dbus_iface.rs @@ -71,6 +71,7 @@ use num_traits::{FromPrimitive, ToPrimitive}; use std::collections::HashMap; use std::convert::{TryFrom, TryInto}; +use std::fs::File; use std::sync::Arc; use btstack::bluetooth_qa::IBluetoothQACallback; @@ -2727,7 +2728,7 @@ impl IBluetoothMedia for BluetoothMediaDBus { } #[dbus_method("StartAudioRequest")] - fn start_audio_request(&mut self) -> bool { + fn start_audio_request(&mut self, connection_listener: File) -> bool { dbus_generated!() } @@ -2737,7 +2738,7 @@ impl IBluetoothMedia for BluetoothMediaDBus { } #[dbus_method("StopAudioRequest")] - fn stop_audio_request(&mut self) { + fn stop_audio_request(&mut self, connection_listener: File) { dbus_generated!() } @@ -2747,6 +2748,7 @@ impl IBluetoothMedia for BluetoothMediaDBus { address: RawAddress, sco_offload: bool, disabled_codecs: HfpCodecBitId, + connection_listener: File, ) -> bool { dbus_generated!() } @@ -2757,7 +2759,7 @@ impl IBluetoothMedia for BluetoothMediaDBus { } #[dbus_method("StopScoCall")] - fn stop_sco_call(&mut self, address: RawAddress) { + fn stop_sco_call(&mut self, address: RawAddress, connection_listener: File) { dbus_generated!() } diff --git a/system/gd/rust/linux/service/src/iface_bluetooth_media.rs b/system/gd/rust/linux/service/src/iface_bluetooth_media.rs index 4cbdef121f3..25ec26a366b 100644 --- a/system/gd/rust/linux/service/src/iface_bluetooth_media.rs +++ b/system/gd/rust/linux/service/src/iface_bluetooth_media.rs @@ -26,6 +26,7 @@ use crate::dbus_arg::{DBusArg, DBusArgError, RefArgToRust}; use num_traits::{FromPrimitive, ToPrimitive}; use std::convert::{TryFrom, TryInto}; +use std::fs::File; use std::sync::Arc; #[allow(dead_code)] @@ -360,7 +361,7 @@ impl IBluetoothMedia for IBluetoothMediaDBus { } #[dbus_method("StartAudioRequest")] - fn start_audio_request(&mut self) -> bool { + fn start_audio_request(&mut self, connection_listener: File) -> bool { dbus_generated!() } @@ -370,7 +371,7 @@ impl IBluetoothMedia for IBluetoothMediaDBus { } #[dbus_method("StopAudioRequest", DBusLog::Disable)] - fn stop_audio_request(&mut self) { + fn stop_audio_request(&mut self, connection_listener: File) { dbus_generated!() } @@ -380,6 +381,7 @@ impl IBluetoothMedia for IBluetoothMediaDBus { address: RawAddress, sco_offload: bool, disabled_codecs: HfpCodecBitId, + connection_listener: File, ) -> bool { dbus_generated!() } @@ -390,7 +392,7 @@ impl IBluetoothMedia for IBluetoothMediaDBus { } #[dbus_method("StopScoCall")] - fn stop_sco_call(&mut self, address: RawAddress) { + fn stop_sco_call(&mut self, address: RawAddress, connection_listener: File) { dbus_generated!() } diff --git a/system/gd/rust/linux/stack/src/bluetooth_media.rs b/system/gd/rust/linux/stack/src/bluetooth_media.rs index 1e4c0383f29..7a146f0914c 100644 --- a/system/gd/rust/linux/stack/src/bluetooth_media.rs +++ b/system/gd/rust/linux/stack/src/bluetooth_media.rs @@ -46,6 +46,8 @@ use itertools::Itertools; use log::{debug, info, warn}; use std::collections::{HashMap, HashSet}; use std::convert::{TryFrom, TryInto}; +use std::fs::File; +use std::io::Write; use std::sync::Arc; use std::sync::Mutex; @@ -151,8 +153,8 @@ pub trait IBluetoothMedia { // Set the HFP speaker volume. Valid volume specified by the HFP spec should // be in the range of 0-15. fn set_hfp_volume(&mut self, volume: u8, address: RawAddress); - fn start_audio_request(&mut self) -> bool; - fn stop_audio_request(&mut self); + fn start_audio_request(&mut self, connection_listener: File) -> bool; + fn stop_audio_request(&mut self, connection_listener: File); /// Returns true iff A2DP audio has started. fn get_a2dp_audio_started(&mut self, address: RawAddress) -> bool; @@ -169,8 +171,9 @@ pub trait IBluetoothMedia { address: RawAddress, sco_offload: bool, disabled_codecs: HfpCodecBitId, + connection_listener: File, ) -> bool; - fn stop_sco_call(&mut self, address: RawAddress); + fn stop_sco_call(&mut self, address: RawAddress, connection_listener: File); /// Set the current playback status: e.g., playing, paused, stopped, etc. The method is a copy /// of the existing CRAS API, hence not following Floss API conventions. @@ -492,6 +495,8 @@ pub struct BluetoothMedia { csis: Option, csis_states: HashMap, is_le_audio_only_enabled: bool, // TODO: remove this once there is dual mode. + hfp_audio_connection_listener: Option, + a2dp_audio_connection_listener: Option, } impl BluetoothMedia { @@ -557,6 +562,8 @@ impl BluetoothMedia { csis: None, csis_states: HashMap::new(), is_le_audio_only_enabled: false, + hfp_audio_connection_listener: None, + a2dp_audio_connection_listener: None, } } @@ -639,6 +646,19 @@ impl BluetoothMedia { } } + fn write_data_to_listener(&self, mut listener: File, data: Vec) { + match listener.write(&data) { + Ok(nwritten) => { + if nwritten != data.len() { + warn!("Did not write full data into the event listener."); + } + } + Err(e) => { + warn!("Cannot write data into the event listener: {}", e); + } + } + } + pub fn set_adapter(&mut self, adapter: Arc>>) { self.adapter = Some(adapter); } @@ -1234,11 +1254,13 @@ impl BluetoothMedia { match state { BtavConnectionState::Connected => { info!("[{}]: a2dp connected.", DisplayAddress(&addr)); + self.a2dp_states.insert(addr, state); self.add_connected_profile(addr, Profile::A2dpSink); } BtavConnectionState::Disconnected => { info!("[{}]: a2dp disconnected.", DisplayAddress(&addr)); + self.a2dp_states.remove(&addr); self.a2dp_caps.remove(&addr); self.a2dp_audio_state.remove(&addr); @@ -1251,6 +1273,18 @@ impl BluetoothMedia { } A2dpCallbacks::AudioState(addr, state) => { info!("[{}]: a2dp audio state: {:?}", DisplayAddress(&addr), state); + + let started: u8 = match state { + BtavAudioState::Started => 1, + _ => 0, + }; + + if self.a2dp_audio_connection_listener.is_some() { + let listener = self.a2dp_audio_connection_listener.take().unwrap(); + let data: Vec = vec![started]; + self.write_data_to_listener(listener, data); + } + self.a2dp_audio_state.insert(addr, state); } A2dpCallbacks::AudioConfig(addr, _config, _local_caps, a2dp_caps) => { @@ -1489,6 +1523,13 @@ impl BluetoothMedia { self.hfp_audio_state.insert(addr, state); + if self.hfp_audio_connection_listener.is_some() { + let listener = self.hfp_audio_connection_listener.take().unwrap(); + let codec = self.get_hfp_audio_final_codecs(addr); + let data: Vec = vec![codec]; + self.write_data_to_listener(listener, data); + } + if self.should_insert_call_when_sco_start(addr) { // This triggers a +CIEV command to set the call status for HFP devices. // It is required for some devices to provide sound. @@ -1499,6 +1540,12 @@ impl BluetoothMedia { BthfAudioState::Disconnected => { info!("[{}]: hfp audio disconnected.", DisplayAddress(&addr)); + if self.hfp_audio_connection_listener.is_some() { + let listener = self.hfp_audio_connection_listener.take().unwrap(); + let data: Vec = vec![0]; + self.write_data_to_listener(listener, data); + } + // Ignore disconnected -> disconnected if let Some(BthfAudioState::Connected) = self.hfp_audio_state.insert(addr, state) @@ -3822,13 +3869,24 @@ impl IBluetoothMedia for BluetoothMedia { }; } - fn start_audio_request(&mut self) -> bool { + fn start_audio_request(&mut self, connection_listener: File) -> bool { + if self.a2dp_audio_connection_listener.is_some() { + warn!("start_audio_request: replacing an unresolved listener"); + } + + self.a2dp_audio_connection_listener = Some(connection_listener); self.start_audio_request_impl() } - fn stop_audio_request(&mut self) { + fn stop_audio_request(&mut self, connection_listener: File) { debug!("Stop audio request"); + if self.a2dp_audio_connection_listener.is_some() { + warn!("stop_audio_request: replacing an unresolved listener"); + } + + self.a2dp_audio_connection_listener = Some(connection_listener); + match self.a2dp.as_mut() { Some(a2dp) => a2dp.stop_audio_request(), None => warn!("Uninitialized A2DP to stop audio request"), @@ -3840,11 +3898,22 @@ impl IBluetoothMedia for BluetoothMedia { address: RawAddress, sco_offload: bool, disabled_codecs: HfpCodecBitId, + connection_listener: File, ) -> bool { + if self.hfp_audio_connection_listener.is_some() { + warn!("start_sco_call: replacing an unresolved listener"); + } + + self.hfp_audio_connection_listener = Some(connection_listener); self.start_sco_call_impl(address, sco_offload, disabled_codecs) } - fn stop_sco_call(&mut self, address: RawAddress) { + fn stop_sco_call(&mut self, address: RawAddress, listener: File) { + if self.hfp_audio_connection_listener.is_some() { + warn!("stop_sco_call: replacing an unresolved listener"); + } + + self.hfp_audio_connection_listener = Some(listener); self.stop_sco_call_impl(address) } -- GitLab From 4083f1a00622b37d1f7777e4b3a35ac7aaf44823 Mon Sep 17 00:00:00 2001 From: Kihong Seong Date: Mon, 17 Jun 2024 03:32:05 +0000 Subject: [PATCH 0029/1446] Add UUID information for log in register scanner function Shim layer register scanner function doesn't have UUID information which makes it hard to distinguish when muiltiple registrations are ongoing. Thus add that information to the log. Bug: 347606822 Test: m com.android.btservices Flag: EXEMPT, adding logs only Change-Id: If805d9888ba6208117cbf78157acd7707331c3a7 --- system/main/shim/le_scanning_manager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/main/shim/le_scanning_manager.cc b/system/main/shim/le_scanning_manager.cc index 8a75023386a..c9b113541ac 100644 --- a/system/main/shim/le_scanning_manager.cc +++ b/system/main/shim/le_scanning_manager.cc @@ -163,8 +163,8 @@ void BleScannerInterfaceImpl::Init() { /** Registers a scanner with the stack */ void BleScannerInterfaceImpl::RegisterScanner(const bluetooth::Uuid& uuid, RegisterCallback) { - log::info("in shim layer"); auto app_uuid = bluetooth::hci::Uuid::From128BitBE(uuid.To128BitBE()); + log::info("in shim layer, UUID={}", app_uuid.ToString()); bluetooth::shim::GetScanning()->RegisterScanner(app_uuid); } -- GitLab From ab46f8b6736260400f7e35bd60308713e39aae75 Mon Sep 17 00:00:00 2001 From: Hyundo Moon Date: Mon, 10 Jun 2024 17:22:05 +0900 Subject: [PATCH 0030/1446] OppService: Make sure ContentObserver is not called after stop Bug: 346179390 Bug: 346467641 Test: atest BluetoothOppServiceCleanupTest BluetoothOppServiceTest Change-Id: Iec360464622643b647fa79657e1228dada03a4e1 --- .../src/com/android/bluetooth/opp/BluetoothOppService.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java index 306faf6182d..f1c5f27a143 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppService.java @@ -118,6 +118,13 @@ public class BluetoothOppService extends ProfileService implements IObexConnecti @Override public void onChange(boolean selfChange) { Log.v(TAG, "ContentObserver received notification"); + + // Since ContentObserver is created with Handler, onChange() can be called + // even after the observer is unregistered. + if (Flags.oppIgnoreContentObserverAfterServiceStop() && mObserver != this) { + Log.d(TAG, "onChange() called after stop() is called."); + return; + } updateFromProvider(); } } -- GitLab From 1c7d38050625bad16e882513a19268da40f3f90e Mon Sep 17 00:00:00 2001 From: "wei11.jiang" Date: Mon, 17 Jun 2024 11:33:58 +0800 Subject: [PATCH 0031/1446] add kSamsungDebugHandle to filter debug logs Do not send acl packets that uses kSamsungDebugHandle (0xeef). Also, do not print "unknow connection" LOG to prevent lots of logs. Test: mmm packages/modules/Bluetooth Bug: 341188860 Flag: EXEMPT, added a debug handle Merged-In: Ib404cbfbdff9094c9d9f8bf2d6e3d87bff96c825 Change-Id: Ia2ba025da0ba0720458558ac89c447d7cb932e9b --- system/gd/hci/acl_manager.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system/gd/hci/acl_manager.cc b/system/gd/hci/acl_manager.cc index 41f44cef913..a1cbf44c24f 100644 --- a/system/gd/hci/acl_manager.cc +++ b/system/gd/hci/acl_manager.cc @@ -43,6 +43,7 @@ namespace bluetooth { namespace hci { constexpr uint16_t kQualcommDebugHandle = 0xedc; +constexpr uint16_t kSamsungDebugHandle = 0xeef; using acl_manager::AclConnection; using common::Bind; @@ -161,7 +162,7 @@ struct AclManager::impl { return; } uint16_t handle = packet->GetHandle(); - if (handle == kQualcommDebugHandle) return; + if (handle == kQualcommDebugHandle || handle == kSamsungDebugHandle) return; if (classic_impl_->send_packet_upward( handle, [&packet](struct acl_manager::assembler* assembler) { assembler->on_incoming_packet(*packet); })) return; -- GitLab From 98ef5cfe1df90b39125fc6c8a380f7d9bd4d2c45 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Mon, 17 Jun 2024 09:29:29 +0000 Subject: [PATCH 0032/1446] floss: update btmanagerd version to 0.7.0 CLs changing the API: * CL:3124915 Bug: 342943472 Tag: #floss Test: m Bluetooth Flag: EXEMPT floss only changes Change-Id: I1b8ecd142175165854002186a623590f2abb6b9b --- system/gd/rust/linux/mgmt/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/gd/rust/linux/mgmt/Cargo.toml b/system/gd/rust/linux/mgmt/Cargo.toml index d6359e646f9..12b88b16833 100644 --- a/system/gd/rust/linux/mgmt/Cargo.toml +++ b/system/gd/rust/linux/mgmt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "manager_service" -version = "0.6.0" +version = "0.7.0" edition = "2018" build = "build.rs" -- GitLab From 4a142625bc0089e8a6213f00a4763b0a32675dab Mon Sep 17 00:00:00 2001 From: Rongxuan Liu Date: Mon, 17 Jun 2024 16:43:42 +0000 Subject: [PATCH 0033/1446] flags: add leaudio_broadcast_update_metadata_callback Notify upper layer with callback when medadata is updated Bug: 347710374 Bug: 315241296 Test: mmm packages/modules/Bluetooth Change-Id: I7011bcf155799435a7acbcfa5bed89072a14ca37 --- flags/leaudio.aconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/flags/leaudio.aconfig b/flags/leaudio.aconfig index 6d476f7f6cc..c8d82799c17 100644 --- a/flags/leaudio.aconfig +++ b/flags/leaudio.aconfig @@ -385,3 +385,13 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "leaudio_broadcast_update_metadata_callback" + namespace: "bluetooth" + description: "Notify upper layer with callback when medadata is updated" + bug: "347710374" + metadata { + purpose: PURPOSE_BUGFIX + } +} -- GitLab From aa54cb5106c33237c0169ba8b59d25af7ddf8a26 Mon Sep 17 00:00:00 2001 From: Ying Hsu Date: Mon, 17 Jun 2024 15:50:26 +0000 Subject: [PATCH 0034/1446] floss: Output dumpsys to a fixed temp file dumpsys command sometimes encounters D-Bus timeout error. This patch mitigates the timeout by writing diagnostic information to a fixed temporary file and returning the file path instead of the content, thereby reducing IO time. Bug: 327542410 Tag: #floss Test: btclient -c dumpsys Test: m com.android.btservices Flag: EXEMPT, floss only change Change-Id: I581ed794d5464531944435b7b34ed38017354503 --- system/gd/rust/linux/stack/Cargo.toml | 1 - system/gd/rust/linux/stack/src/bluetooth.rs | 13 +++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/system/gd/rust/linux/stack/Cargo.toml b/system/gd/rust/linux/stack/Cargo.toml index 4ff90b58c19..9ad6b63ace9 100644 --- a/system/gd/rust/linux/stack/Cargo.toml +++ b/system/gd/rust/linux/stack/Cargo.toml @@ -23,7 +23,6 @@ num-traits = "0.2" rand = { version = "0.8.3", features = ["small_rng"] } serde_json = "1.0" syslog = "6" -tempfile = "3.10" tokio = { version = "1", features = ['bytes', 'fs', 'io-util', 'libc', 'macros', 'mio', 'net', 'num_cpus', 'rt', 'rt-multi-thread', 'sync', 'time', 'tokio-macros'] } [lib] diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs index 7898e8b57bc..8196bb4a66b 100644 --- a/system/gd/rust/linux/stack/src/bluetooth.rs +++ b/system/gd/rust/linux/stack/src/bluetooth.rs @@ -31,7 +31,7 @@ use num_traits::cast::ToPrimitive; use num_traits::pow; use std::collections::{HashMap, HashSet}; use std::convert::TryInto; -use std::fs::File; +use std::fs::{File, OpenOptions}; use std::hash::Hash; use std::io::Write; use std::os::fd::AsRawFd; @@ -39,7 +39,6 @@ use std::process; use std::sync::{Arc, Condvar, Mutex}; use std::time::Duration; use std::time::Instant; -use tempfile::NamedTempFile; use tokio::sync::mpsc::Sender; use tokio::task::JoinHandle; use tokio::time; @@ -70,6 +69,8 @@ const BTM_SUCCESS: i32 = 0; const PID_DIR: &str = "/var/run/bluetooth"; +const DUMPSYS_LOG: &str = "/tmp/dumpsys.log"; + /// Represents various roles the adapter supports. #[derive(Debug, FromPrimitive, ToPrimitive)] #[repr(u32)] @@ -3005,11 +3006,15 @@ impl IBluetooth for Bluetooth { } fn get_dumpsys(&self) -> String { - NamedTempFile::new() + OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(DUMPSYS_LOG) .and_then(|file| { let fd = file.as_raw_fd(); self.intf.lock().unwrap().dump(fd); - std::fs::read_to_string(file.path()) + Ok(format!("dump to {}", DUMPSYS_LOG)) }) .unwrap_or_default() } -- GitLab From fa631e72d90a49e8e91cc46e8f6f7d1bd40c7770 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Thu, 13 Jun 2024 07:54:51 -0700 Subject: [PATCH 0035/1446] stack::inq Finalize extract inquiry API Inquiry API resides in dedicated header file Bug: 346991067 Test: m . Flag: EXEMPT, Mechanical Refactor Change-Id: I888d08f12975970a51b7da91b138decd2c5b8edb --- system/bta/dm/bta_dm_act.cc | 1 + system/stack/btm/btm_inq.cc | 3 +- system/stack/include/btm_api.h | 117 --------------------------------- system/stack/include/btm_inq.h | 36 ++++++++-- 4 files changed, 32 insertions(+), 125 deletions(-) diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc index 585b4198455..a199c45a293 100644 --- a/system/bta/dm/bta_dm_act.cc +++ b/system/bta/dm/bta_dm_act.cc @@ -58,6 +58,7 @@ #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" #include "stack/include/btm_client_interface.h" +#include "stack/include/btm_inq.h" #include "stack/include/gatt_api.h" #include "stack/include/l2c_api.h" #include "stack/include/main_thread.h" diff --git a/system/stack/btm/btm_inq.cc b/system/stack/btm/btm_inq.cc index 758f2b2ec6e..e55d5d17e3f 100644 --- a/system/stack/btm/btm_inq.cc +++ b/system/stack/btm/btm_inq.cc @@ -42,7 +42,7 @@ #include "common/time_util.h" #include "hci/controller_interface.h" #include "hci/event_checkers.h" -#include "hci/hci_layer.h" +#include "hci/hci_interface.h" #include "internal_include/bt_target.h" #include "main/shim/acl_api.h" #include "main/shim/entry.h" @@ -62,7 +62,6 @@ #include "stack/include/bt_lap.h" #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" -#include "stack/include/btm_api.h" #include "stack/include/btm_ble_api.h" #include "stack/include/btm_log_history.h" #include "stack/include/hci_error_code.h" diff --git a/system/stack/include/btm_api.h b/system/stack/include/btm_api.h index 5d5082903c2..d629a625cc1 100644 --- a/system/stack/include/btm_api.h +++ b/system/stack/include/btm_api.h @@ -168,123 +168,6 @@ void BTM_WriteVoiceSettings(uint16_t settings); ******************************************************************************/ [[nodiscard]] tBTM_STATUS BTM_EnableTestMode(void); -/******************************************************************************* - * DEVICE DISCOVERY FUNCTIONS - Inquiry, Remote Name, Discovery, Class of Device - ******************************************************************************/ - -/******************************************************************************* - * - * Function BTM_SetDiscoverability - * - * Description This function is called to set the device into or out of - * discoverable mode. Discoverable mode means inquiry - * scans are enabled. If a value of '0' is entered for window - * or interval, the default values are used. - * - * Returns BTM_SUCCESS if successful - * BTM_BUSY if a setting of the filter is already in progress - * BTM_NO_RESOURCES if couldn't get a memory pool buffer - * BTM_ILLEGAL_VALUE if a bad parameter was detected - * BTM_WRONG_MODE if the device is not up. - * - ******************************************************************************/ -[[nodiscard]] tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode); - -/******************************************************************************* - * - * Function BTM_StartInquiry - * - * Description This function is called to start an inquiry. - * - * Parameters: p_inqparms - pointer to the inquiry information - * mode - GENERAL or LIMITED inquiry - * duration - length in 1.28 sec intervals (If '0', the - * inquiry is CANCELLED) - * filter_cond_type - BTM_CLR_INQUIRY_FILTER, - * BTM_FILTER_COND_DEVICE_CLASS, or - * BTM_FILTER_COND_BD_ADDR - * filter_cond - value for the filter (based on - * filter_cond_type) - * - * p_results_cb - Pointer to the callback routine which gets - * called upon receipt of an inquiry result. If - * this field is NULL, the application is not - * notified. - * - * p_cmpl_cb - Pointer to the callback routine which gets - * called upon completion. If this field is - * NULL, the application is not notified when - * completed. - * Returns tBTM_STATUS - * BTM_CMD_STARTED if successfully initiated - * BTM_BUSY if already in progress - * BTM_ILLEGAL_VALUE if parameter(s) are out of range - * BTM_NO_RESOURCES if could not allocate resources to start - * the command - * BTM_WRONG_MODE if the device is not up. - * - ******************************************************************************/ -[[nodiscard]] tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, - tBTM_CMPL_CB* p_cmpl_cb); - -/******************************************************************************* - * - * Function BTM_IsInquiryActive - * - * Description Return a bit mask of the current inquiry state - * - * Returns Bitmask of current inquiry state - * - ******************************************************************************/ -[[nodiscard]] uint16_t BTM_IsInquiryActive(void); - -/******************************************************************************* - * - * Function BTM_CancelInquiry - * - * Description This function cancels an inquiry if active - * - ******************************************************************************/ -void BTM_CancelInquiry(void); - -/******************************************************************************* - * - * Function BTM_SetConnectability - * - * Description This function is called to set the device into or out of - * connectable mode. Discoverable mode means page scans are - * enabled. - * - * Returns BTM_SUCCESS if successful - * BTM_ILLEGAL_VALUE if a bad parameter is detected - * BTM_NO_RESOURCES if could not allocate a message buffer - * BTM_WRONG_MODE if the device is not up. - * - ******************************************************************************/ -[[nodiscard]] tBTM_STATUS BTM_SetConnectability(uint16_t page_mode); - -/******************************************************************************* - * - * Function BTM_SetInquiryMode - * - * Description This function is called to set standard, with RSSI - * mode or extended of the inquiry for local device. - * - * Input Params: BTM_INQ_RESULT_STANDARD, BTM_INQ_RESULT_WITH_RSSI or - * BTM_INQ_RESULT_EXTENDED - * - * Returns BTM_SUCCESS if successful - * BTM_NO_RESOURCES if couldn't get a memory pool buffer - * BTM_ILLEGAL_VALUE if a bad parameter was detected - * BTM_WRONG_MODE if the device is not up. - * - ******************************************************************************/ -[[nodiscard]] tBTM_STATUS BTM_SetInquiryMode(uint8_t mode); - -void BTM_EnableInterlacedInquiryScan(); - -void BTM_EnableInterlacedPageScan(); - /******************************************************************************* * * Function BTM_ReadRemoteDeviceName diff --git a/system/stack/include/btm_inq.h b/system/stack/include/btm_inq.h index 103fbe56310..40a8f5b29c3 100644 --- a/system/stack/include/btm_inq.h +++ b/system/stack/include/btm_inq.h @@ -38,7 +38,7 @@ * BTM_WRONG_MODE if the device is not up. * ******************************************************************************/ -tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode); +[[nodiscard]] tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode); /******************************************************************************* * @@ -74,8 +74,8 @@ tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode); * BTM_WRONG_MODE if the device is not up. * ******************************************************************************/ -tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, - tBTM_CMPL_CB* p_cmpl_cb); +[[nodiscard]] tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, + tBTM_CMPL_CB* p_cmpl_cb); /******************************************************************************* * @@ -86,7 +86,7 @@ tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, * Returns Bitmask of current inquiry state * ******************************************************************************/ -uint16_t BTM_IsInquiryActive(void); +[[nodiscard]] uint16_t BTM_IsInquiryActive(void); /******************************************************************************* * @@ -111,7 +111,7 @@ void BTM_CancelInquiry(void); * BTM_WRONG_MODE if the device is not up. * ******************************************************************************/ -tBTM_STATUS BTM_SetConnectability(uint16_t page_mode); +[[nodiscard]] tBTM_STATUS BTM_SetConnectability(uint16_t page_mode); /******************************************************************************* * @@ -129,8 +129,32 @@ tBTM_STATUS BTM_SetConnectability(uint16_t page_mode); * BTM_WRONG_MODE if the device is not up. * ******************************************************************************/ -tBTM_STATUS BTM_SetInquiryMode(uint8_t mode); +[[nodiscard]] tBTM_STATUS BTM_SetInquiryMode(uint8_t mode); +/******************************************************************************* + * + * Function BTM_EnableInterlacedInquiryScan + * + * Description Reads system property PROPERTY_INQ_SCAN_TYPE and + * enables interlaced inquiry scan with controller support. + * + * Input Params: None + * + * Returns void + * + ******************************************************************************/ void BTM_EnableInterlacedInquiryScan(); +/******************************************************************************* + * + * Function BTM_EnableInterlacedPageScan + * + * Description Reads system property PROPERTY_PAGE_SCAN_TYPE and + * enables interlaced page scan with controller support. + * + * Input Params: None + * + * Returns void + * + ******************************************************************************/ void BTM_EnableInterlacedPageScan(); -- GitLab From d782eb683af4369e41e3981f6028411ba0e2bbeb Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Tue, 4 Jun 2024 15:06:29 -0700 Subject: [PATCH 0036/1446] Use proper types stack::l2cap::tL2CAP_DW_RESULT Bug: 344989901 Test: m . Flag: EXEMPT, Mechanical Refactor Change-Id: Ic904eeea4b4a45c1fa8f1c2a99c14177847ea204 --- system/stack/avdt/avdt_ad.cc | 4 +-- system/stack/avdt/avdt_int.h | 4 +-- system/stack/fuzzers/sdp_fuzzer.cc | 6 ++-- system/stack/gap/gap_conn.cc | 2 +- system/stack/gatt/att_protocol.cc | 4 +-- system/stack/hid/hidd_conn.cc | 2 +- system/stack/hid/hidh_conn.cc | 2 +- system/stack/include/l2c_api.h | 11 ++++---- system/stack/l2cap/l2c_api.cc | 9 +++--- system/stack/l2cap/l2c_int.h | 2 +- system/stack/l2cap/l2c_main.cc | 2 +- system/stack/smp/smp_utils.cc | 2 +- system/stack/test/common/mock_l2cap_layer.cc | 2 +- system/stack/test/common/mock_l2cap_layer.h | 4 +-- system/stack/test/sdp/stack_sdp_parse_test.cc | 2 +- system/stack/test/sdp/stack_sdp_test.cc | 6 ++-- system/stack/test/sdp/stack_sdp_utils_test.cc | 6 ++-- system/test/mock/mock_stack_l2cap_api.cc | 9 +++--- system/test/mock/mock_stack_l2cap_api.h | 28 +++++++++++-------- system/test/mock/mock_stack_l2cap_main.cc | 6 ++-- 20 files changed, 61 insertions(+), 52 deletions(-) diff --git a/system/stack/avdt/avdt_ad.cc b/system/stack/avdt/avdt_ad.cc index e556e6b6c68..8702e1d6928 100644 --- a/system/stack/avdt/avdt_ad.cc +++ b/system/stack/avdt/avdt_ad.cc @@ -483,8 +483,8 @@ void avdt_ad_tc_data_ind(AvdtpTransportChannel* p_tbl, BT_HDR* p_buf) { * AVDT_AD_FAILED, if error * ******************************************************************************/ -uint8_t avdt_ad_write_req(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb, - BT_HDR* p_buf) { +tL2CAP_DW_RESULT avdt_ad_write_req(uint8_t type, AvdtpCcb* p_ccb, + AvdtpScb* p_scb, BT_HDR* p_buf) { uint8_t tcid; /* get tcid from type, scb */ diff --git a/system/stack/avdt/avdt_int.h b/system/stack/avdt/avdt_int.h index 0d476bc8c20..3bc2e777529 100644 --- a/system/stack/avdt/avdt_int.h +++ b/system/stack/avdt/avdt_int.h @@ -929,8 +929,8 @@ void avdt_ad_tc_cong_ind(AvdtpTransportChannel* p_tbl, bool is_congested); void avdt_ad_tc_data_ind(AvdtpTransportChannel* p_tbl, BT_HDR* p_buf); AvdtpTransportChannel* avdt_ad_tc_tbl_by_type(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb); -uint8_t avdt_ad_write_req(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb, - BT_HDR* p_buf); +tL2CAP_DW_RESULT avdt_ad_write_req(uint8_t type, AvdtpCcb* p_ccb, + AvdtpScb* p_scb, BT_HDR* p_buf); void avdt_ad_open_req(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb, uint8_t role); void avdt_ad_close_req(uint8_t type, AvdtpCcb* p_ccb, AvdtpScb* p_scb); diff --git a/system/stack/fuzzers/sdp_fuzzer.cc b/system/stack/fuzzers/sdp_fuzzer.cc index e2bc87f7f48..8f7c2d3dcf0 100644 --- a/system/stack/fuzzers/sdp_fuzzer.cc +++ b/system/stack/fuzzers/sdp_fuzzer.cc @@ -87,11 +87,11 @@ class FakeL2cap { [](uint16_t psm, const RawAddress& p_bd_addr, uint16_t sec_level) { return L2CA_ConnectReq(psm, p_bd_addr); }; - test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t cid, - BT_HDR* p_data) { + test::mock::stack_l2cap_api::L2CA_DataWrite.body = + [](uint16_t cid, BT_HDR* p_data) -> tL2CAP_DW_RESULT { auto len = p_data->len; osi_free(p_data); - return (uint8_t)len; + return L2CAP_DW_SUCCESS; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t lcid) { return true; diff --git a/system/stack/gap/gap_conn.cc b/system/stack/gap/gap_conn.cc index 7e2f9665b56..fe0164bde1c 100644 --- a/system/stack/gap/gap_conn.cc +++ b/system/stack/gap/gap_conn.cc @@ -434,7 +434,7 @@ static bool gap_try_write_queued_data(tGAP_CCB* p_ccb) { /* Send the buffer through L2CAP */ BT_HDR* p_buf; while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->tx_queue)) != NULL) { - uint8_t status; + tL2CAP_DW_RESULT status; if (p_ccb->transport == BT_TRANSPORT_LE) { status = L2CA_LECocDataWrite(p_ccb->connection_id, p_buf); } else { diff --git a/system/stack/gatt/att_protocol.cc b/system/stack/gatt/att_protocol.cc index 6cfd5a4509f..9fcb2c9b43c 100644 --- a/system/stack/gatt/att_protocol.cc +++ b/system/stack/gatt/att_protocol.cc @@ -373,14 +373,14 @@ static BT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code, ******************************************************************************/ tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB& tcb, uint16_t lcid, BT_HDR* p_toL2CAP) { - uint16_t l2cap_ret; + tL2CAP_DW_RESULT l2cap_ret; if (lcid == L2CAP_ATT_CID) { log::debug("Sending ATT message on att fixed channel"); l2cap_ret = L2CA_SendFixedChnlData(lcid, tcb.peer_bda, p_toL2CAP); } else { log::debug("Sending ATT message on lcid:{}", lcid); - l2cap_ret = (uint16_t)L2CA_DataWrite(lcid, p_toL2CAP); + l2cap_ret = L2CA_DataWrite(lcid, p_toL2CAP); } if (l2cap_ret == L2CAP_DW_FAILED) { diff --git a/system/stack/hid/hidd_conn.cc b/system/stack/hid/hidd_conn.cc index 54ffdd60c2f..c6debe12f13 100644 --- a/system/stack/hid/hidd_conn.cc +++ b/system/stack/hid/hidd_conn.cc @@ -822,7 +822,7 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, log::verbose("report sent"); - if (!L2CA_DataWrite(cid, p_buf)) { + if (L2CA_DataWrite(cid, p_buf) == L2CAP_DW_FAILED) { log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDD_ERR_CONGESTED_AT_DATA_WRITE, 1); diff --git a/system/stack/hid/hidh_conn.cc b/system/stack/hid/hidh_conn.cc index d0a6b04a977..e3d90fe09c9 100644 --- a/system/stack/hid/hidh_conn.cc +++ b/system/stack/hid/hidh_conn.cc @@ -848,7 +848,7 @@ tHID_STATUS hidh_conn_snd_data(uint8_t dhandle, uint8_t trans_type, /* Send the buffer through L2CAP */ if ((p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) || - (!L2CA_DataWrite(cid, p_buf))) { + (L2CA_DataWrite(cid, p_buf) == L2CAP_DW_FAILED)) { log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDH_ERR_CONGESTED_AT_SEND_DATA, 1); diff --git a/system/stack/include/l2c_api.h b/system/stack/include/l2c_api.h index d967a833929..855d0d7da6c 100644 --- a/system/stack/include/l2c_api.h +++ b/system/stack/include/l2c_api.h @@ -584,9 +584,10 @@ void L2CA_DeregisterLECoc(uint16_t psm); * L2CAP_DW_FAILED, if error * ******************************************************************************/ -[[nodiscard]] uint8_t L2CA_DataWrite(uint16_t cid, BT_HDR* p_data); +[[nodiscard]] tL2CAP_DW_RESULT L2CA_DataWrite(uint16_t cid, BT_HDR* p_data); -[[nodiscard]] uint8_t L2CA_LECocDataWrite(uint16_t cid, BT_HDR* p_data); +[[nodiscard]] tL2CAP_DW_RESULT L2CA_LECocDataWrite(uint16_t cid, + BT_HDR* p_data); /******************************************************************************* * @@ -809,9 +810,9 @@ typedef struct { * L2CAP_DW_FAILED, if error * ******************************************************************************/ -[[nodiscard]] uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, - const RawAddress& rem_bda, - BT_HDR* p_buf); +[[nodiscard]] tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, + const RawAddress& rem_bda, + BT_HDR* p_buf); /******************************************************************************* * diff --git a/system/stack/l2cap/l2c_api.cc b/system/stack/l2cap/l2c_api.cc index f32fd71f857..f43c139c6af 100644 --- a/system/stack/l2cap/l2c_api.cc +++ b/system/stack/l2cap/l2c_api.cc @@ -1287,8 +1287,9 @@ bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) { * L2CAP_DW_FAILED, if error * ******************************************************************************/ -uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda, - BT_HDR* p_buf) { +tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, + const RawAddress& rem_bda, + BT_HDR* p_buf) { tL2C_LCB* p_lcb; tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; @@ -1501,12 +1502,12 @@ bool L2CA_MarkLeLinkAsActive(const RawAddress& rem_bda) { * L2CAP_DW_FAILED, if error * ******************************************************************************/ -uint8_t L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { +tL2CAP_DW_RESULT L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { log::verbose("L2CA_DataWrite() CID: 0x{:04x} Len: {}", cid, p_data->len); return l2c_data_write(cid, p_data, L2CAP_FLUSHABLE_CH_BASED); } -uint8_t L2CA_LECocDataWrite(uint16_t cid, BT_HDR* p_data) { +tL2CAP_DW_RESULT L2CA_LECocDataWrite(uint16_t cid, BT_HDR* p_data) { return L2CA_DataWrite(cid, p_data); } diff --git a/system/stack/l2cap/l2c_int.h b/system/stack/l2cap/l2c_int.h index e441f6fdc68..2853b14e846 100644 --- a/system/stack/l2cap/l2c_int.h +++ b/system/stack/l2cap/l2c_int.h @@ -701,7 +701,7 @@ void l2c_receive_hold_timer_timeout(void* data); void l2c_ccb_timer_timeout(void* data); void l2c_lcb_timer_timeout(void* data); void l2c_fcrb_ack_timer_timeout(void* data); -uint8_t l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flag); +tL2CAP_DW_RESULT l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flag); void l2c_acl_flush(uint16_t handle); tL2C_LCB* l2cu_allocate_lcb(const RawAddress& p_bd_addr, bool is_bonding, diff --git a/system/stack/l2cap/l2c_main.cc b/system/stack/l2cap/l2c_main.cc index 6634b7bab79..dd17a5f8412 100644 --- a/system/stack/l2cap/l2c_main.cc +++ b/system/stack/l2cap/l2c_main.cc @@ -906,7 +906,7 @@ void l2c_lcb_timer_timeout(void* data) { * L2CAP_DW_FAILED, if error * ******************************************************************************/ -uint8_t l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flags) { +tL2CAP_DW_RESULT l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flags) { /* Find the channel control block. We don't know the link it is on. */ tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(NULL, cid); if (!p_ccb) { diff --git a/system/stack/smp/smp_utils.cc b/system/stack/smp/smp_utils.cc index eee342b5997..60cd2310dc3 100644 --- a/system/stack/smp/smp_utils.cc +++ b/system/stack/smp/smp_utils.cc @@ -351,7 +351,7 @@ void smp_log_metrics(const RawAddress& bd_addr, bool is_outgoing, * ******************************************************************************/ bool smp_send_msg_to_L2CAP(const RawAddress& rem_bda, BT_HDR* p_toL2CAP) { - uint16_t l2cap_ret; + tL2CAP_DW_RESULT l2cap_ret; uint16_t fixed_cid = L2CAP_SMP_CID; if (smp_cb.smp_over_br) { diff --git a/system/stack/test/common/mock_l2cap_layer.cc b/system/stack/test/common/mock_l2cap_layer.cc index c1fe394c17e..109e8eb619c 100644 --- a/system/stack/test/common/mock_l2cap_layer.cc +++ b/system/stack/test/common/mock_l2cap_layer.cc @@ -67,7 +67,7 @@ bool L2CA_ConfigRsp(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) { return l2cap_interface->ConfigResponse(cid, p_cfg); } -uint8_t L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { +tL2CAP_DW_RESULT L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { return l2cap_interface->DataWrite(cid, p_data); } diff --git a/system/stack/test/common/mock_l2cap_layer.h b/system/stack/test/common/mock_l2cap_layer.h index 81e76b0ec1d..869eeb044c6 100644 --- a/system/stack/test/common/mock_l2cap_layer.h +++ b/system/stack/test/common/mock_l2cap_layer.h @@ -41,7 +41,7 @@ class L2capInterface { virtual bool DisconnectResponse(uint16_t cid) = 0; virtual bool ConfigRequest(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) = 0; virtual bool ConfigResponse(uint16_t cid, tL2CAP_CFG_INFO* p_cfg) = 0; - virtual uint8_t DataWrite(uint16_t cid, BT_HDR* p_data) = 0; + virtual tL2CAP_DW_RESULT DataWrite(uint16_t cid, BT_HDR* p_data) = 0; virtual uint16_t RegisterLECoc(uint16_t psm, const tL2CAP_APPL_INFO &cb_info, uint16_t sec_level) = 0; virtual void DeregisterLECoc(uint16_t psm) = 0; virtual bool ConnectCreditBasedRsp(const RawAddress& bd_addr, uint8_t id, @@ -72,7 +72,7 @@ class MockL2capInterface : public L2capInterface { MOCK_METHOD1(DisconnectResponse, bool(uint16_t cid)); MOCK_METHOD2(ConfigRequest, bool(uint16_t cid, tL2CAP_CFG_INFO* p_cfg)); MOCK_METHOD2(ConfigResponse, bool(uint16_t cid, tL2CAP_CFG_INFO* p_cfg)); - MOCK_METHOD2(DataWrite, uint8_t(uint16_t cid, BT_HDR* p_data)); + MOCK_METHOD2(DataWrite, tL2CAP_DW_RESULT(uint16_t cid, BT_HDR* p_data)); MOCK_METHOD3(RegisterLECoc, uint16_t(uint16_t psm, const tL2CAP_APPL_INFO &cb_info, uint16_t sec_level)); MOCK_METHOD1(DeregisterLECoc, void(uint16_t psm)); diff --git a/system/stack/test/sdp/stack_sdp_parse_test.cc b/system/stack/test/sdp/stack_sdp_parse_test.cc index 1d00401c8cc..0d5f339d9de 100644 --- a/system/stack/test/sdp/stack_sdp_parse_test.cc +++ b/system/stack/test/sdp/stack_sdp_parse_test.cc @@ -63,7 +63,7 @@ class StackSdpParserWithMocksTest : public ::testing::Test { test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t /* cid */, BT_HDR* p_data) { osi_free_and_reset((void**)&p_data); - return 0; + return L2CAP_DW_FAILED; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t /* cid */) { return true; }; diff --git a/system/stack/test/sdp/stack_sdp_test.cc b/system/stack/test/sdp/stack_sdp_test.cc index 5c9223011ee..aa3db3c9eb4 100644 --- a/system/stack/test/sdp/stack_sdp_test.cc +++ b/system/stack/test/sdp/stack_sdp_test.cc @@ -49,10 +49,10 @@ class StackSdpWithMocksTest : public ::testing::Test { uint16_t /* sec_level */) { return ++L2CA_ConnectReqWithSecurity_cid; }; - test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t /* cid */, - BT_HDR* p_data) { + test::mock::stack_l2cap_api::L2CA_DataWrite.body = + [](uint16_t /* cid */, BT_HDR* p_data) -> tL2CAP_DW_RESULT { osi_free_and_reset((void**)&p_data); - return 0; + return L2CAP_DW_FAILED; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t /* cid */) { return true; }; diff --git a/system/stack/test/sdp/stack_sdp_utils_test.cc b/system/stack/test/sdp/stack_sdp_utils_test.cc index e3cfac1ddbd..21ddc87fd38 100644 --- a/system/stack/test/sdp/stack_sdp_utils_test.cc +++ b/system/stack/test/sdp/stack_sdp_utils_test.cc @@ -254,10 +254,10 @@ class StackSdpMockAndFakeTest : public ::testing::Test { uint16_t /* sec_level */) { return ++L2CA_ConnectReqWithSecurity_cid; }; - test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t /* cid */, - BT_HDR* p_data) { + test::mock::stack_l2cap_api::L2CA_DataWrite.body = + [](uint16_t /* cid */, BT_HDR* p_data) -> tL2CAP_DW_RESULT { osi_free_and_reset((void**)&p_data); - return 0; + return L2CAP_DW_FAILED; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t /* cid */) { return true; }; diff --git a/system/test/mock/mock_stack_l2cap_api.cc b/system/test/mock/mock_stack_l2cap_api.cc index ffd7435050e..b70e4eacd44 100644 --- a/system/test/mock/mock_stack_l2cap_api.cc +++ b/system/test/mock/mock_stack_l2cap_api.cc @@ -216,8 +216,9 @@ bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) { inc_func_call_count(__func__); return test::mock::stack_l2cap_api::L2CA_ConnectFixedChnl(fixed_cid, rem_bda); } -uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda, - BT_HDR* p_buf) { +tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, + const RawAddress& rem_bda, + BT_HDR* p_buf) { inc_func_call_count(__func__); return test::mock::stack_l2cap_api::L2CA_SendFixedChnlData(fixed_cid, rem_bda, p_buf); @@ -234,11 +235,11 @@ bool L2CA_MarkLeLinkAsActive(const RawAddress& rem_bda) { inc_func_call_count(__func__); return test::mock::stack_l2cap_api::L2CA_MarkLeLinkAsActive(rem_bda); } -uint8_t L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { +tL2CAP_DW_RESULT L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { inc_func_call_count(__func__); return test::mock::stack_l2cap_api::L2CA_DataWrite(cid, p_data); } -uint8_t L2CA_LECocDataWrite(uint16_t cid, BT_HDR* p_data) { +tL2CAP_DW_RESULT L2CA_LECocDataWrite(uint16_t cid, BT_HDR* p_data) { inc_func_call_count(__func__); return test::mock::stack_l2cap_api::L2CA_LECocDataWrite(cid, p_data); } diff --git a/system/test/mock/mock_stack_l2cap_api.h b/system/test/mock/mock_stack_l2cap_api.h index 768d37039fe..f4249ef2444 100644 --- a/system/test/mock/mock_stack_l2cap_api.h +++ b/system/test/mock/mock_stack_l2cap_api.h @@ -375,12 +375,14 @@ extern struct L2CA_ConnectFixedChnl L2CA_ConnectFixedChnl; // Params: uint16_t fixed_cid, const RawAddress& rem_bda, BT_HDR* p_buf // Returns: uint16_t struct L2CA_SendFixedChnlData { - std::function + std::function body{[](uint16_t /* fixed_cid */, const RawAddress& /* rem_bda */, - BT_HDR* /* p_buf */) { return 0; }}; - uint16_t operator()(uint16_t fixed_cid, const RawAddress& rem_bda, - BT_HDR* p_buf) { + BT_HDR* /* p_buf */) -> tL2CAP_DW_RESULT { + return L2CAP_DW_FAILED; + }}; + tL2CAP_DW_RESULT operator()(uint16_t fixed_cid, const RawAddress& rem_bda, + BT_HDR* p_buf) { return body(fixed_cid, rem_bda, p_buf); }; }; @@ -424,9 +426,11 @@ extern struct L2CA_MarkLeLinkAsActive L2CA_MarkLeLinkAsActive; // Params: uint16_t cid, BT_HDR* p_data // Returns: uint8_t struct L2CA_DataWrite { - std::function body{ - [](uint16_t /* cid */, BT_HDR* /* p_data */) { return 0; }}; - uint8_t operator()(uint16_t cid, BT_HDR* p_data) { + std::function body{ + [](uint16_t /* cid */, BT_HDR* /* p_data */) -> tL2CAP_DW_RESULT { + return L2CAP_DW_FAILED; + }}; + tL2CAP_DW_RESULT operator()(uint16_t cid, BT_HDR* p_data) { return body(cid, p_data); }; }; @@ -435,9 +439,11 @@ extern struct L2CA_DataWrite L2CA_DataWrite; // Params: uint16_t cid, BT_HDR* p_data // Returns: uint8_t struct L2CA_LECocDataWrite { - std::function body{ - [](uint16_t /* cid */, BT_HDR* /* p_data */) { return 0; }}; - uint8_t operator()(uint16_t cid, BT_HDR* p_data) { + std::function body{ + [](uint16_t /* cid */, BT_HDR* /* p_data */) -> tL2CAP_DW_RESULT { + return L2CAP_DW_FAILED; + }}; + tL2CAP_DW_RESULT operator()(uint16_t cid, BT_HDR* p_data) { return body(cid, p_data); }; }; diff --git a/system/test/mock/mock_stack_l2cap_main.cc b/system/test/mock/mock_stack_l2cap_main.cc index 9ff48db9fec..68729ad4dee 100644 --- a/system/test/mock/mock_stack_l2cap_main.cc +++ b/system/test/mock/mock_stack_l2cap_main.cc @@ -24,10 +24,10 @@ #include "stack/l2cap/l2c_int.h" #include "test/common/mock_functions.h" -uint8_t l2c_data_write(uint16_t /* cid */, BT_HDR* /* p_data */, - uint16_t /* flags */) { +tL2CAP_DW_RESULT l2c_data_write(uint16_t /* cid */, BT_HDR* /* p_data */, + uint16_t /* flags */) { inc_func_call_count(__func__); - return 0; + return L2CAP_DW_FAILED; } void l2c_ccb_timer_timeout(void* /* data */) { inc_func_call_count(__func__); } void l2c_fcrb_ack_timer_timeout(void* /* data */) { -- GitLab From 8480bd44b5a0da5c39bf7609737a60c04097a847 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Wed, 5 Jun 2024 16:05:22 -0700 Subject: [PATCH 0037/1446] stack::btm::rnr: BTM_CancelRemoteDeviceName Fail early Bug: 345308047 Test: m . Flag: EXEMPT, Mechanical Refactor Change-Id: I55c893706a0654799c8a6b403a7c8cdfffe426e2 --- system/stack/btm/btm_inq.cc | 41 +++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/system/stack/btm/btm_inq.cc b/system/stack/btm/btm_inq.cc index 758f2b2ec6e..0304b87218c 100644 --- a/system/stack/btm/btm_inq.cc +++ b/system/stack/btm/btm_inq.cc @@ -860,28 +860,29 @@ tBTM_STATUS BTM_CancelRemoteDeviceName(void) { bool is_le; /* Make sure there is not already one in progress */ - if (btm_cb.btm_inq_vars.remname_active) { - if (com::android::bluetooth::flags::rnr_store_device_type()) { - is_le = (btm_cb.btm_inq_vars.remname_dev_type == BT_DEVICE_TYPE_BLE); - } else { - is_le = BTM_UseLeLink(btm_cb.btm_inq_vars.remname_bda); - } + if (!btm_cb.btm_inq_vars.remname_active) { + return (BTM_WRONG_MODE); + } - if (is_le) { - /* Cancel remote name request for LE device, and process remote name - * callback. */ - btm_inq_rmt_name_failed_cancelled(); - } else { - bluetooth::shim::ACL_CancelRemoteNameRequest( - btm_cb.btm_inq_vars.remname_bda); - if (com::android::bluetooth::flags::rnr_reset_state_at_cancel()) { - btm_process_remote_name(&btm_cb.btm_inq_vars.remname_bda, nullptr, 0, - HCI_ERR_UNSPECIFIED); - } + if (com::android::bluetooth::flags::rnr_store_device_type()) { + is_le = (btm_cb.btm_inq_vars.remname_dev_type == BT_DEVICE_TYPE_BLE); + } else { + is_le = BTM_UseLeLink(btm_cb.btm_inq_vars.remname_bda); + } + + if (is_le) { + /* Cancel remote name request for LE device, and process remote name + * callback. */ + btm_inq_rmt_name_failed_cancelled(); + } else { + bluetooth::shim::ACL_CancelRemoteNameRequest( + btm_cb.btm_inq_vars.remname_bda); + if (com::android::bluetooth::flags::rnr_reset_state_at_cancel()) { + btm_process_remote_name(&btm_cb.btm_inq_vars.remname_bda, nullptr, 0, + HCI_ERR_UNSPECIFIED); } - return (BTM_CMD_STARTED); - } else - return (BTM_WRONG_MODE); + } + return (BTM_CMD_STARTED); } /******************************************************************************* -- GitLab From 7045395dbaf197c2598628ec0fb3164c3276028f Mon Sep 17 00:00:00 2001 From: Rongxuan Liu Date: Mon, 17 Jun 2024 18:15:42 +0000 Subject: [PATCH 0038/1446] [le audio] Fix defNoPAS default value DefNoPAS is used to indicate NO PAST. We should use default as false here. Tag: #bug Bug: 330690507 Bug: 333050419 Test: atest BassClientServiceTest Test: atest BassClientStateMachineTest Change-Id: Iebea554c4f27ed8b701b1b785d63c6a14c4169f7 --- .../android/bluetooth/bass_client/BassClientService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 f5c34b52865..b0e54ca5246 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java +++ b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java @@ -3097,9 +3097,9 @@ public class BassClientService extends ProfileService { DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_BLUETOOTH, "persist.vendor.service.bt.defNoPAS", - true) - ? BassConstants.PA_SYNC_PAST_AVAILABLE - : BassConstants.PA_SYNC_PAST_NOT_AVAILABLE; + false) + ? BassConstants.PA_SYNC_PAST_NOT_AVAILABLE + : BassConstants.PA_SYNC_PAST_AVAILABLE; message.obj = metadata; stateMachine.sendMessage(message); } else { -- GitLab From d85ddd2e596b5afcfec3fd4d061b671b4f424e1e Mon Sep 17 00:00:00 2001 From: Liana Kazanova Date: Mon, 17 Jun 2024 20:00:11 +0000 Subject: [PATCH 0039/1446] Revert "stack::inq Finalize extract inquiry API" This reverts commit fa631e72d90a49e8e91cc46e8f6f7d1bd40c7770. Reason for revert: DroidMonitor: Potential culprit for b/347743665 - verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted. Change-Id: I18183c56475348ba7caed62eeddb448d006f6a19 --- system/bta/dm/bta_dm_act.cc | 1 - system/stack/btm/btm_inq.cc | 3 +- system/stack/include/btm_api.h | 117 +++++++++++++++++++++++++++++++++ system/stack/include/btm_inq.h | 36 ++-------- 4 files changed, 125 insertions(+), 32 deletions(-) diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc index a199c45a293..585b4198455 100644 --- a/system/bta/dm/bta_dm_act.cc +++ b/system/bta/dm/bta_dm_act.cc @@ -58,7 +58,6 @@ #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" #include "stack/include/btm_client_interface.h" -#include "stack/include/btm_inq.h" #include "stack/include/gatt_api.h" #include "stack/include/l2c_api.h" #include "stack/include/main_thread.h" diff --git a/system/stack/btm/btm_inq.cc b/system/stack/btm/btm_inq.cc index e55d5d17e3f..758f2b2ec6e 100644 --- a/system/stack/btm/btm_inq.cc +++ b/system/stack/btm/btm_inq.cc @@ -42,7 +42,7 @@ #include "common/time_util.h" #include "hci/controller_interface.h" #include "hci/event_checkers.h" -#include "hci/hci_interface.h" +#include "hci/hci_layer.h" #include "internal_include/bt_target.h" #include "main/shim/acl_api.h" #include "main/shim/entry.h" @@ -62,6 +62,7 @@ #include "stack/include/bt_lap.h" #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" +#include "stack/include/btm_api.h" #include "stack/include/btm_ble_api.h" #include "stack/include/btm_log_history.h" #include "stack/include/hci_error_code.h" diff --git a/system/stack/include/btm_api.h b/system/stack/include/btm_api.h index d629a625cc1..5d5082903c2 100644 --- a/system/stack/include/btm_api.h +++ b/system/stack/include/btm_api.h @@ -168,6 +168,123 @@ void BTM_WriteVoiceSettings(uint16_t settings); ******************************************************************************/ [[nodiscard]] tBTM_STATUS BTM_EnableTestMode(void); +/******************************************************************************* + * DEVICE DISCOVERY FUNCTIONS - Inquiry, Remote Name, Discovery, Class of Device + ******************************************************************************/ + +/******************************************************************************* + * + * Function BTM_SetDiscoverability + * + * Description This function is called to set the device into or out of + * discoverable mode. Discoverable mode means inquiry + * scans are enabled. If a value of '0' is entered for window + * or interval, the default values are used. + * + * Returns BTM_SUCCESS if successful + * BTM_BUSY if a setting of the filter is already in progress + * BTM_NO_RESOURCES if couldn't get a memory pool buffer + * BTM_ILLEGAL_VALUE if a bad parameter was detected + * BTM_WRONG_MODE if the device is not up. + * + ******************************************************************************/ +[[nodiscard]] tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode); + +/******************************************************************************* + * + * Function BTM_StartInquiry + * + * Description This function is called to start an inquiry. + * + * Parameters: p_inqparms - pointer to the inquiry information + * mode - GENERAL or LIMITED inquiry + * duration - length in 1.28 sec intervals (If '0', the + * inquiry is CANCELLED) + * filter_cond_type - BTM_CLR_INQUIRY_FILTER, + * BTM_FILTER_COND_DEVICE_CLASS, or + * BTM_FILTER_COND_BD_ADDR + * filter_cond - value for the filter (based on + * filter_cond_type) + * + * p_results_cb - Pointer to the callback routine which gets + * called upon receipt of an inquiry result. If + * this field is NULL, the application is not + * notified. + * + * p_cmpl_cb - Pointer to the callback routine which gets + * called upon completion. If this field is + * NULL, the application is not notified when + * completed. + * Returns tBTM_STATUS + * BTM_CMD_STARTED if successfully initiated + * BTM_BUSY if already in progress + * BTM_ILLEGAL_VALUE if parameter(s) are out of range + * BTM_NO_RESOURCES if could not allocate resources to start + * the command + * BTM_WRONG_MODE if the device is not up. + * + ******************************************************************************/ +[[nodiscard]] tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, + tBTM_CMPL_CB* p_cmpl_cb); + +/******************************************************************************* + * + * Function BTM_IsInquiryActive + * + * Description Return a bit mask of the current inquiry state + * + * Returns Bitmask of current inquiry state + * + ******************************************************************************/ +[[nodiscard]] uint16_t BTM_IsInquiryActive(void); + +/******************************************************************************* + * + * Function BTM_CancelInquiry + * + * Description This function cancels an inquiry if active + * + ******************************************************************************/ +void BTM_CancelInquiry(void); + +/******************************************************************************* + * + * Function BTM_SetConnectability + * + * Description This function is called to set the device into or out of + * connectable mode. Discoverable mode means page scans are + * enabled. + * + * Returns BTM_SUCCESS if successful + * BTM_ILLEGAL_VALUE if a bad parameter is detected + * BTM_NO_RESOURCES if could not allocate a message buffer + * BTM_WRONG_MODE if the device is not up. + * + ******************************************************************************/ +[[nodiscard]] tBTM_STATUS BTM_SetConnectability(uint16_t page_mode); + +/******************************************************************************* + * + * Function BTM_SetInquiryMode + * + * Description This function is called to set standard, with RSSI + * mode or extended of the inquiry for local device. + * + * Input Params: BTM_INQ_RESULT_STANDARD, BTM_INQ_RESULT_WITH_RSSI or + * BTM_INQ_RESULT_EXTENDED + * + * Returns BTM_SUCCESS if successful + * BTM_NO_RESOURCES if couldn't get a memory pool buffer + * BTM_ILLEGAL_VALUE if a bad parameter was detected + * BTM_WRONG_MODE if the device is not up. + * + ******************************************************************************/ +[[nodiscard]] tBTM_STATUS BTM_SetInquiryMode(uint8_t mode); + +void BTM_EnableInterlacedInquiryScan(); + +void BTM_EnableInterlacedPageScan(); + /******************************************************************************* * * Function BTM_ReadRemoteDeviceName diff --git a/system/stack/include/btm_inq.h b/system/stack/include/btm_inq.h index 40a8f5b29c3..103fbe56310 100644 --- a/system/stack/include/btm_inq.h +++ b/system/stack/include/btm_inq.h @@ -38,7 +38,7 @@ * BTM_WRONG_MODE if the device is not up. * ******************************************************************************/ -[[nodiscard]] tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode); +tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode); /******************************************************************************* * @@ -74,8 +74,8 @@ * BTM_WRONG_MODE if the device is not up. * ******************************************************************************/ -[[nodiscard]] tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, - tBTM_CMPL_CB* p_cmpl_cb); +tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, + tBTM_CMPL_CB* p_cmpl_cb); /******************************************************************************* * @@ -86,7 +86,7 @@ * Returns Bitmask of current inquiry state * ******************************************************************************/ -[[nodiscard]] uint16_t BTM_IsInquiryActive(void); +uint16_t BTM_IsInquiryActive(void); /******************************************************************************* * @@ -111,7 +111,7 @@ void BTM_CancelInquiry(void); * BTM_WRONG_MODE if the device is not up. * ******************************************************************************/ -[[nodiscard]] tBTM_STATUS BTM_SetConnectability(uint16_t page_mode); +tBTM_STATUS BTM_SetConnectability(uint16_t page_mode); /******************************************************************************* * @@ -129,32 +129,8 @@ void BTM_CancelInquiry(void); * BTM_WRONG_MODE if the device is not up. * ******************************************************************************/ -[[nodiscard]] tBTM_STATUS BTM_SetInquiryMode(uint8_t mode); +tBTM_STATUS BTM_SetInquiryMode(uint8_t mode); -/******************************************************************************* - * - * Function BTM_EnableInterlacedInquiryScan - * - * Description Reads system property PROPERTY_INQ_SCAN_TYPE and - * enables interlaced inquiry scan with controller support. - * - * Input Params: None - * - * Returns void - * - ******************************************************************************/ void BTM_EnableInterlacedInquiryScan(); -/******************************************************************************* - * - * Function BTM_EnableInterlacedPageScan - * - * Description Reads system property PROPERTY_PAGE_SCAN_TYPE and - * enables interlaced page scan with controller support. - * - * Input Params: None - * - * Returns void - * - ******************************************************************************/ void BTM_EnableInterlacedPageScan(); -- GitLab From 4dddbdda5ce8ee6bb04e6a518de20126b85b6119 Mon Sep 17 00:00:00 2001 From: Brian Delwiche Date: Fri, 5 Apr 2024 00:41:49 +0000 Subject: [PATCH 0040/1446] Fix OOB read in bta_av_setconfig_rej The bta_av_config_ind function in bta_av_aact.cc makes a call in some user journeys to bta_av_setconfig_rej, constructing its p_data argument (a union datatype) as a tBTA_AV_CI_SETCONFIG. This is a valid member of the union, but bta_av_setconfig_rej makes the assumption that the variable being passed has been set up as a tBTA_AV_STR_MSG, which is not true in this case. This causes OOB access. Draw the required data instead from the stream control block, which should not be subject to this confusion. Bug: 260230151 Bug: 341754333 Flag: bta_av_setconfig_rej_type_confusion Test: m libbluetooth Ignore-AOSP-First: security Tag: #security Change-Id: Id6cdb2b5a5e0b25d0926a83d09b68c483bd0df98 --- system/bta/av/bta_av_aact.cc | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/system/bta/av/bta_av_aact.cc b/system/bta/av/bta_av_aact.cc index 3dabb8d17d7..74a4b88818d 100644 --- a/system/bta/av/bta_av_aact.cc +++ b/system/bta/av/bta_av_aact.cc @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -1816,13 +1817,25 @@ void bta_av_setconfig_rej(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { p_scb->avdt_handle, p_scb->hndl); AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_UNSUP_CFG, 0); - tBTA_AV bta_av_data = { - .reject = - { - .bd_addr = p_data->str_msg.bd_addr, - .hndl = p_scb->hndl, - }, - }; + tBTA_AV bta_av_data; + + if (com::android::bluetooth::flags::bta_av_setconfig_rej_type_confusion()) { + bta_av_data = { + .reject = + { + .bd_addr = p_scb->PeerAddress(), + .hndl = p_scb->hndl, + }, + }; + } else { + bta_av_data = { + .reject = + { + .bd_addr = p_data->str_msg.bd_addr, + .hndl = p_scb->hndl, + }, + }; + } (*bta_av_cb.p_cback)(BTA_AV_REJECT_EVT, &bta_av_data); } -- GitLab From b151f31f330a77776485302b9d1cceb49e73fe4e Mon Sep 17 00:00:00 2001 From: Rongxuan Liu Date: Mon, 17 Jun 2024 20:30:41 +0000 Subject: [PATCH 0041/1446] Remove released flag divide_long_single_gap_data Test: atest bluetooth_test_gd_unit Bug: 310217895 Bug: 303546333 Change-Id: Icf7d6b352d66baee500182ec1d49785d3b817637 --- flags/gap.aconfig | 7 - system/gd/hci/le_advertising_manager.cc | 236 ++++++------------- system/gd/hci/le_advertising_manager_test.cc | 45 +--- 3 files changed, 83 insertions(+), 205 deletions(-) diff --git a/flags/gap.aconfig b/flags/gap.aconfig index d485195945b..6539df36866 100644 --- a/flags/gap.aconfig +++ b/flags/gap.aconfig @@ -8,13 +8,6 @@ flag { bug: "308855997" } -flag { - name: "divide_long_single_gap_data" - namespace: "bluetooth" - description: "Divide long single gap data if length is longer than HCI data length limit" - bug: "310217895" -} - flag { name: "fix_nonconnectable_scannable_advertisement" namespace: "bluetooth" diff --git a/system/gd/hci/le_advertising_manager.cc b/system/gd/hci/le_advertising_manager.cc index 7680476d11b..5dee840f3c1 100644 --- a/system/gd/hci/le_advertising_manager.cc +++ b/system/gd/hci/le_advertising_manager.cc @@ -955,13 +955,10 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb bool check_extended_advertising_data(std::vector data, bool include_flag) { uint16_t data_len = 0; - uint16_t data_limit = com::android::bluetooth::flags::divide_long_single_gap_data() - ? kLeMaximumGapDataLength - : kLeMaximumFragmentLength; // check data size for (size_t i = 0; i < data.size(); i++) { - if (data[i].size() > data_limit) { - log::warn("AD data len shall not greater than {}", data_limit); + if (data[i].size() > kLeMaximumGapDataLength) { + log::warn("AD data len shall not greater than {}", kLeMaximumGapDataLength); return false; } data_len += data[i].size(); @@ -1053,13 +1050,10 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb } break; case (AdvertisingApiType::EXTENDED): { uint16_t data_len = 0; - bool divide_gap_flag = com::android::bluetooth::flags::divide_long_single_gap_data(); // check data size for (size_t i = 0; i < data.size(); i++) { - uint16_t data_limit = - divide_gap_flag ? kLeMaximumGapDataLength : kLeMaximumFragmentLength; - if (data[i].size() > data_limit) { - log::warn("AD data len shall not greater than {}", data_limit); + if (data[i].size() > kLeMaximumGapDataLength) { + log::warn("AD data len shall not greater than {}", kLeMaximumGapDataLength); if (advertising_callbacks_ != nullptr) { if (set_scan_rsp) { advertising_callbacks_->OnScanResponseDataSet( @@ -1101,35 +1095,21 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb uint16_t sub_data_len = 0; Operation operation = Operation::FIRST_FRAGMENT; - if (divide_gap_flag) { - std::vector> fragments; - packet::FragmentingInserter it( - kLeMaximumFragmentLength, std::back_insert_iterator(fragments)); - for (auto gap_data : data) { - gap_data.Serialize(it); - } - it.finalize(); + std::vector> fragments; + packet::FragmentingInserter it( + kLeMaximumFragmentLength, std::back_insert_iterator(fragments)); + for (auto gap_data : data) { + gap_data.Serialize(it); + } + it.finalize(); - for (size_t i = 0; i < fragments.size(); i++) { - send_data_fragment_with_raw_builder( - advertiser_id, - set_scan_rsp, - std::move(fragments[i]), - (i == fragments.size() - 1) ? Operation::LAST_FRAGMENT : operation); - operation = Operation::INTERMEDIATE_FRAGMENT; - } - } else { - for (size_t i = 0; i < data.size(); i++) { - if (sub_data_len + data[i].size() > kLeMaximumFragmentLength) { - send_data_fragment(advertiser_id, set_scan_rsp, sub_data, operation); - operation = Operation::INTERMEDIATE_FRAGMENT; - sub_data_len = 0; - sub_data.clear(); - } - sub_data.push_back(data[i]); - sub_data_len += data[i].size(); - } - send_data_fragment(advertiser_id, set_scan_rsp, sub_data, Operation::LAST_FRAGMENT); + for (size_t i = 0; i < fragments.size(); i++) { + send_data_fragment_with_raw_builder( + advertiser_id, + set_scan_rsp, + std::move(fragments[i]), + (i == fragments.size() - 1) ? Operation::LAST_FRAGMENT : operation); + operation = Operation::INTERMEDIATE_FRAGMENT; } } } break; @@ -1137,65 +1117,31 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb } void send_data_fragment( - AdvertiserId advertiser_id, bool set_scan_rsp, std::vector data, Operation operation) { - if (com::android::bluetooth::flags::divide_long_single_gap_data()) { - // For first and intermediate fragment, do not trigger advertising_callbacks_. - bool send_callback = - (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT); - if (set_scan_rsp) { - le_advertising_interface_->EnqueueCommand( - hci::LeSetExtendedScanResponseDataBuilder::Create( - advertiser_id, operation, kFragment_preference, data), - module_handler_->BindOnceOn( - this, - &impl::check_status_with_id, - send_callback, - advertiser_id)); - } else { - le_advertising_interface_->EnqueueCommand( - hci::LeSetExtendedAdvertisingDataBuilder::Create( - advertiser_id, operation, kFragment_preference, data), - module_handler_->BindOnceOn( - this, - &impl::check_status_with_id, - send_callback, - advertiser_id)); - } + AdvertiserId advertiser_id, + bool set_scan_rsp, + std::vector data, + Operation operation) { + // For first and intermediate fragment, do not trigger advertising_callbacks_. + bool send_callback = + (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT); + if (set_scan_rsp) { + le_advertising_interface_->EnqueueCommand( + hci::LeSetExtendedScanResponseDataBuilder::Create( + advertiser_id, operation, kFragment_preference, data), + module_handler_->BindOnceOn( + this, + &impl::check_status_with_id, + send_callback, + advertiser_id)); } else { - if (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT) { - if (set_scan_rsp) { - le_advertising_interface_->EnqueueCommand( - hci::LeSetExtendedScanResponseDataBuilder::Create( - advertiser_id, operation, kFragment_preference, data), - module_handler_->BindOnceOn( - this, - &impl::check_status_with_id, - true, - advertiser_id)); - } else { - le_advertising_interface_->EnqueueCommand( - hci::LeSetExtendedAdvertisingDataBuilder::Create( - advertiser_id, operation, kFragment_preference, data), - module_handler_->BindOnceOn( - this, - &impl::check_status_with_id, - true, - advertiser_id)); - } - } else { - // For first and intermediate fragment, do not trigger advertising_callbacks_. - if (set_scan_rsp) { - le_advertising_interface_->EnqueueCommand( - hci::LeSetExtendedScanResponseDataBuilder::Create( - advertiser_id, operation, kFragment_preference, data), - module_handler_->BindOnce(check_complete)); - } else { - le_advertising_interface_->EnqueueCommand( - hci::LeSetExtendedAdvertisingDataBuilder::Create( - advertiser_id, operation, kFragment_preference, data), - module_handler_->BindOnce(check_complete)); - } - } + le_advertising_interface_->EnqueueCommand( + hci::LeSetExtendedAdvertisingDataBuilder::Create( + advertiser_id, operation, kFragment_preference, data), + module_handler_->BindOnceOn( + this, + &impl::check_status_with_id, + send_callback, + advertiser_id)); } } @@ -1315,12 +1261,10 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb void set_periodic_data(AdvertiserId advertiser_id, std::vector data) { uint16_t data_len = 0; - bool divide_gap_flag = com::android::bluetooth::flags::divide_long_single_gap_data(); // check data size for (size_t i = 0; i < data.size(); i++) { - uint16_t data_limit = divide_gap_flag ? kLeMaximumGapDataLength : kLeMaximumFragmentLength; - if (data[i].size() > data_limit) { - log::warn("AD data len shall not greater than {}", data_limit); + if (data[i].size() > kLeMaximumGapDataLength) { + log::warn("AD data len shall not greater than {}", kLeMaximumGapDataLength); if (advertising_callbacks_ != nullptr) { advertising_callbacks_->OnPeriodicAdvertisingDataSet( advertiser_id, AdvertisingCallback::AdvertisingStatus::INTERNAL_ERROR); @@ -1341,75 +1285,43 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb return; } - uint16_t data_fragment_limit = - divide_gap_flag ? kLeMaximumPeriodicDataFragmentLength : kLeMaximumFragmentLength; - if (data_len <= data_fragment_limit) { + if (data_len <= kLeMaximumPeriodicDataFragmentLength) { send_periodic_data_fragment(advertiser_id, data, Operation::COMPLETE_ADVERTISEMENT); } else { std::vector sub_data; uint16_t sub_data_len = 0; Operation operation = Operation::FIRST_FRAGMENT; - if (divide_gap_flag) { - std::vector> fragments; - packet::FragmentingInserter it( - kLeMaximumPeriodicDataFragmentLength, std::back_insert_iterator(fragments)); - for (auto gap_data : data) { - gap_data.Serialize(it); - } - it.finalize(); + std::vector> fragments; + packet::FragmentingInserter it( + kLeMaximumPeriodicDataFragmentLength, std::back_insert_iterator(fragments)); + for (auto gap_data : data) { + gap_data.Serialize(it); + } + it.finalize(); - for (size_t i = 0; i < fragments.size(); i++) { - send_periodic_data_fragment_with_raw_builder( - advertiser_id, - std::move(fragments[i]), - (i == fragments.size() - 1) ? Operation::LAST_FRAGMENT : operation); - operation = Operation::INTERMEDIATE_FRAGMENT; - } - } else { - for (size_t i = 0; i < data.size(); i++) { - if (sub_data_len + data[i].size() > kLeMaximumFragmentLength) { - send_periodic_data_fragment(advertiser_id, sub_data, operation); - operation = Operation::INTERMEDIATE_FRAGMENT; - sub_data_len = 0; - sub_data.clear(); - } - sub_data.push_back(data[i]); - sub_data_len += data[i].size(); - } - send_periodic_data_fragment(advertiser_id, sub_data, Operation::LAST_FRAGMENT); + for (size_t i = 0; i < fragments.size(); i++) { + send_periodic_data_fragment_with_raw_builder( + advertiser_id, + std::move(fragments[i]), + (i == fragments.size() - 1) ? Operation::LAST_FRAGMENT : operation); + operation = Operation::INTERMEDIATE_FRAGMENT; } } } - void send_periodic_data_fragment(AdvertiserId advertiser_id, std::vector data, Operation operation) { - if (com::android::bluetooth::flags::divide_long_single_gap_data()) { - // For first and intermediate fragment, do not trigger advertising_callbacks_. - bool send_callback = - (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT); - le_advertising_interface_->EnqueueCommand( - hci::LeSetPeriodicAdvertisingDataBuilder::Create(advertiser_id, operation, data), - module_handler_->BindOnceOn( - this, - &impl::check_status_with_id, - send_callback, - advertiser_id)); - } else { - if (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT) { - le_advertising_interface_->EnqueueCommand( - hci::LeSetPeriodicAdvertisingDataBuilder::Create(advertiser_id, operation, data), - module_handler_->BindOnceOn( - this, - &impl::check_status_with_id, - true, - advertiser_id)); - } else { - // For first and intermediate fragment, do not trigger advertising_callbacks_. - le_advertising_interface_->EnqueueCommand( - hci::LeSetPeriodicAdvertisingDataBuilder::Create(advertiser_id, operation, data), - module_handler_->BindOnce(check_complete)); - } - } + void send_periodic_data_fragment( + AdvertiserId advertiser_id, std::vector data, Operation operation) { + // For first and intermediate fragment, do not trigger advertising_callbacks_. + bool send_callback = + (operation == Operation::COMPLETE_ADVERTISEMENT || operation == Operation::LAST_FRAGMENT); + le_advertising_interface_->EnqueueCommand( + hci::LeSetPeriodicAdvertisingDataBuilder::Create(advertiser_id, operation, data), + module_handler_->BindOnceOn( + this, + &impl::check_status_with_id, + send_callback, + advertiser_id)); } void send_periodic_data_fragment_with_raw_builder( @@ -1772,11 +1684,9 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb return; } - if (com::android::bluetooth::flags::divide_long_single_gap_data()) { - // Do not trigger callback if send_callback is false - if (!send_callback) { - return; - } + // Do not trigger callback if send_callback is false + if (!send_callback) { + return; } OpCode opcode = view.GetCommandOpCode(); diff --git a/system/gd/hci/le_advertising_manager_test.cc b/system/gd/hci/le_advertising_manager_test.cc index ffc42733e9c..251ec5936eb 100644 --- a/system/gd/hci/le_advertising_manager_test.cc +++ b/system/gd/hci/le_advertising_manager_test.cc @@ -788,10 +788,7 @@ TEST_F(LeExtendedAdvertisingManagerTest, create_periodic_advertiser_test) { ASSERT_EQ(OpCode::LE_REMOVE_ADVERTISING_SET, test_hci_layer_->GetCommand().GetOpCode()); } -TEST_F_WITH_FLAGS( - LeExtendedAdvertisingManagerTest, - create_advertiser_valid_max_251_ad_data_length_test, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, divide_long_single_gap_data))) { +TEST_F(LeExtendedAdvertisingManagerTest, create_advertiser_valid_max_251_ad_data_length_test) { AdvertisingConfig advertising_config{}; advertising_config.advertising_type = AdvertisingType::ADV_IND; advertising_config.requested_advertiser_address_type = AdvertiserAddressType::PUBLIC; @@ -849,10 +846,9 @@ TEST_F_WITH_FLAGS( ASSERT_EQ(OpCode::LE_REMOVE_ADVERTISING_SET, test_hci_layer_->GetCommand().GetOpCode()); } -TEST_F_WITH_FLAGS( +TEST_F( LeExtendedAdvertisingManagerTest, - create_advertiser_valid_max_252_ad_data_length_fragments_test, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, divide_long_single_gap_data))) { + create_advertiser_valid_max_252_ad_data_length_fragments_test) { AdvertisingConfig advertising_config{}; advertising_config.advertising_type = AdvertisingType::ADV_IND; advertising_config.requested_advertiser_address_type = AdvertiserAddressType::PUBLIC; @@ -918,10 +914,7 @@ TEST_F_WITH_FLAGS( ASSERT_EQ(OpCode::LE_REMOVE_ADVERTISING_SET, test_hci_layer_->GetCommand().GetOpCode()); } -TEST_F_WITH_FLAGS( - LeExtendedAdvertisingManagerTest, - create_advertiser_test_invalid_256_ad_data_length_test, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, divide_long_single_gap_data))) { +TEST_F(LeExtendedAdvertisingManagerTest, create_advertiser_test_invalid_256_ad_data_length_test) { AdvertisingConfig advertising_config{}; advertising_config.advertising_type = AdvertisingType::ADV_IND; advertising_config.requested_advertiser_address_type = AdvertiserAddressType::PUBLIC; @@ -1279,10 +1272,7 @@ TEST_F(LeExtendedAdvertisingAPITest, set_data_with_invalid_length) { sync_client_handler(); } -TEST_F_WITH_FLAGS( - LeExtendedAdvertisingAPITest, - set_data_valid_max_251_ad_data_length_test, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, divide_long_single_gap_data))) { +TEST_F(LeExtendedAdvertisingAPITest, set_data_valid_max_251_ad_data_length_test) { // Set advertising data std::vector advertising_data{}; // set data 251 bytes @@ -1317,10 +1307,7 @@ TEST_F_WITH_FLAGS( LeSetExtendedScanResponseDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); } -TEST_F_WITH_FLAGS( - LeExtendedAdvertisingAPITest, - set_data_valid_252_ad_data_length_fragments_test, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, divide_long_single_gap_data))) { +TEST_F(LeExtendedAdvertisingAPITest, set_data_valid_252_ad_data_length_fragments_test) { // Set advertising data std::vector advertising_data{}; // set data 252 bytes @@ -1391,10 +1378,7 @@ TEST_F_WITH_FLAGS( LeSetExtendedScanResponseDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); } -TEST_F_WITH_FLAGS( - LeExtendedAdvertisingAPITest, - set_data_with_invalid_256_ad_data_length_test, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, divide_long_single_gap_data))) { +TEST_F(LeExtendedAdvertisingAPITest, set_data_with_invalid_256_ad_data_length_test) { // Set advertising data with data that greater than le_maximum_advertising_data_length_ std::vector advertising_data{}; @@ -1586,10 +1570,7 @@ TEST_F(LeExtendedAdvertisingAPITest, set_periodic_data_fragments_test) { test_hci_layer_->IncomingEvent(LeSetPeriodicAdvertisingDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); } -TEST_F_WITH_FLAGS( - LeExtendedAdvertisingAPITest, - set_periodic_data_valid_max_252_ad_data_length_test, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, divide_long_single_gap_data))) { +TEST_F(LeExtendedAdvertisingAPITest, set_periodic_data_valid_max_252_ad_data_length_test) { // Set advertising data std::vector advertising_data{}; @@ -1612,10 +1593,7 @@ TEST_F_WITH_FLAGS( sync_client_handler(); } -TEST_F_WITH_FLAGS( - LeExtendedAdvertisingAPITest, - set_periodic_data_valid_253_ad_data_length_fragments_test, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, divide_long_single_gap_data))) { +TEST_F(LeExtendedAdvertisingAPITest, set_periodic_data_valid_253_ad_data_length_fragments_test) { // Set advertising data std::vector advertising_data{}; @@ -1653,10 +1631,7 @@ TEST_F_WITH_FLAGS( LeSetPeriodicAdvertisingDataCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); } -TEST_F_WITH_FLAGS( - LeExtendedAdvertisingAPITest, - set_periodic_data_invalid_256_ad_data_length_test, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, divide_long_single_gap_data))) { +TEST_F(LeExtendedAdvertisingAPITest, set_periodic_data_invalid_256_ad_data_length_test) { // Set advertising data std::vector advertising_data{}; -- GitLab From 5da60cfcd95a9ed6e3c7e0adebd42b0b6f986b65 Mon Sep 17 00:00:00 2001 From: Rongxuan Liu Date: Mon, 17 Jun 2024 20:48:25 +0000 Subject: [PATCH 0042/1446] Remove released flag leaudio_enable_health_based_actions Test: atest bluetooth_le_audio_client_test Test: mmm packages/modules/Bluetooth Bug: 301448525 Bug: 290845728 Change-Id: I32d24c3700c115efdc86ea74bf40a7fdd800a5ac --- flags/leaudio.aconfig | 7 ----- system/bta/le_audio/client.cc | 10 +++---- system/bta/le_audio/le_audio_client_test.cc | 32 ++++++--------------- system/bta/le_audio/state_machine.cc | 5 ---- 4 files changed, 12 insertions(+), 42 deletions(-) diff --git a/flags/leaudio.aconfig b/flags/leaudio.aconfig index c8d82799c17..fa63e5eba11 100644 --- a/flags/leaudio.aconfig +++ b/flags/leaudio.aconfig @@ -17,13 +17,6 @@ flag { bug: "307408418" } -flag { - name: "leaudio_enable_health_based_actions" - namespace: "bluetooth" - description: "Le audio device and group health actions for fallback mechanism" - bug: "290845728" -} - flag { name: "leaudio_broadcast_audio_handover_policies" namespace: "bluetooth" diff --git a/system/bta/le_audio/client.cc b/system/bta/le_audio/client.cc index f8064806218..f7672627a10 100644 --- a/system/bta/le_audio/client.cc +++ b/system/bta/le_audio/client.cc @@ -267,12 +267,10 @@ class LeAudioClientImpl : public LeAudioClient { reconnection_mode_ = BTM_BLE_BKG_CONNECT_ALLOW_LIST; } - if (com::android::bluetooth::flags::leaudio_enable_health_based_actions()) { - log::info("Loading health status module"); - leAudioHealthStatus_ = LeAudioHealthStatus::Get(); - leAudioHealthStatus_->RegisterCallback( - base::BindRepeating(le_audio_health_status_callback)); - } + log::info("Loading health status module"); + leAudioHealthStatus_ = LeAudioHealthStatus::Get(); + leAudioHealthStatus_->RegisterCallback( + base::BindRepeating(le_audio_health_status_callback)); BTA_GATTC_AppRegister( le_audio_gattc_callback, diff --git a/system/bta/le_audio/le_audio_client_test.cc b/system/bta/le_audio/le_audio_client_test.cc index a70defd2d57..9658e99787a 100644 --- a/system/bta/le_audio/le_audio_client_test.cc +++ b/system/bta/le_audio/le_audio_client_test.cc @@ -3166,10 +3166,7 @@ TEST_F(UnicastTest, ConnectOneEarbudWithInvalidCsis) { Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); } -TEST_F_WITH_FLAGS(UnicastTestHealthStatus, - ConnectOneEarbudEmpty_withHealthStatus, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( - TEST_BT, leaudio_enable_health_based_actions))) { +TEST_F(UnicastTestHealthStatus, ConnectOneEarbudEmpty_withHealthStatus) { const RawAddress test_address0 = GetTestAddress(0); SetSampleDatabaseEmpty(1, test_address0); EXPECT_CALL(mock_audio_hal_client_callbacks_, @@ -3189,10 +3186,7 @@ TEST_F_WITH_FLAGS(UnicastTestHealthStatus, test_address0, bluetooth::groups::kGroupUnknown); } -TEST_F_WITH_FLAGS(UnicastTestHealthStatus, - ConnectOneEarbudNoPacs_withHealthStatus, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( - TEST_BT, leaudio_enable_health_based_actions))) { +TEST_F(UnicastTestHealthStatus, ConnectOneEarbudNoPacs_withHealthStatus) { const RawAddress test_address0 = GetTestAddress(0); SetSampleDatabaseEarbudsValid( 1, test_address0, codec_spec_conf::kLeAudioLocationStereo, @@ -3219,10 +3213,7 @@ TEST_F_WITH_FLAGS(UnicastTestHealthStatus, test_address0, bluetooth::groups::kGroupUnknown); } -TEST_F_WITH_FLAGS(UnicastTestHealthStatus, - ConnectOneEarbudNoAscs_withHealthStatus, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( - TEST_BT, leaudio_enable_health_based_actions))) { +TEST_F(UnicastTestHealthStatus, ConnectOneEarbudNoAscs_withHealthStatus) { const RawAddress test_address0 = GetTestAddress(0); SetSampleDatabaseEarbudsValid( 1, test_address0, codec_spec_conf::kLeAudioLocationStereo, @@ -3301,10 +3292,8 @@ TEST_F(UnicastTestHealthStatus, ConnectOneEarbudNoCsis_withHealthStatus) { test_address0, bluetooth::groups::kGroupUnknown); } -TEST_F_WITH_FLAGS(UnicastTestHealthStatus, - ConnectOneEarbudWithInvalidCsis_withHealthStatus, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( - TEST_BT, leaudio_enable_health_based_actions))) { +TEST_F(UnicastTestHealthStatus, + ConnectOneEarbudWithInvalidCsis_withHealthStatus) { const RawAddress test_address0 = GetTestAddress(0); SetSampleDatabaseEarbudsValid( 1, test_address0, codec_spec_conf::kLeAudioLocationStereo, @@ -3343,10 +3332,7 @@ TEST_F_WITH_FLAGS(UnicastTestHealthStatus, test_address0, bluetooth::groups::kGroupUnknown); } -TEST_F_WITH_FLAGS(UnicastTestHealthStatus, - ConnectOneEarbudDisable_withHealthStatus, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( - TEST_BT, leaudio_enable_health_based_actions))) { +TEST_F(UnicastTestHealthStatus, ConnectOneEarbudDisable_withHealthStatus) { const RawAddress test_address0 = GetTestAddress(0); int conn_id = 1; @@ -3401,10 +3387,8 @@ TEST_F_WITH_FLAGS(UnicastTestHealthStatus, Mock::VerifyAndClearExpectations(&mock_audio_hal_client_callbacks_); } -TEST_F_WITH_FLAGS(UnicastTestHealthStatus, - ConnectOneEarbudConsiderDisabling_withHealthStatus, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( - TEST_BT, leaudio_enable_health_based_actions))) { +TEST_F(UnicastTestHealthStatus, + ConnectOneEarbudConsiderDisabling_withHealthStatus) { const RawAddress test_address0 = GetTestAddress(0); int conn_id = 1; diff --git a/system/bta/le_audio/state_machine.cc b/system/bta/le_audio/state_machine.cc index 385391dfd9c..61e747d0b48 100644 --- a/system/bta/le_audio/state_machine.cc +++ b/system/bta/le_audio/state_machine.cc @@ -330,11 +330,6 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { void notifyLeAudioHealth( LeAudioDeviceGroup* group, bluetooth::le_audio::LeAudioHealthGroupStatType stat) { - if (!com::android::bluetooth::flags:: - leaudio_enable_health_based_actions()) { - return; - } - auto leAudioHealthStatus = bluetooth::le_audio::LeAudioHealthStatus::Get(); if (leAudioHealthStatus) { leAudioHealthStatus->AddStatisticForGroup(group, stat); -- GitLab From a9a9aa944911d34db604a59ef4346526d0c7e95c Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Fri, 14 Jun 2024 10:55:18 -0700 Subject: [PATCH 0043/1446] stack::sec::btm_sec_rmt_name_request_complete Move declaration/assignment to usage Bug: 347309588 Test: m . Flag: EXMEPT, Mechanical Refactor Change-Id: I5e513a64d9f051908c78a4f6fc6fef44aba3af66 --- system/stack/btm/btm_sec.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/system/stack/btm/btm_sec.cc b/system/stack/btm/btm_sec.cc index fd2f0fbab05..a277a2b9722 100644 --- a/system/stack/btm/btm_sec.cc +++ b/system/stack/btm/btm_sec.cc @@ -2280,9 +2280,6 @@ static void call_registered_rmt_name_callbacks(const RawAddress* p_bd_addr, void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, const uint8_t* p_bd_name, tHCI_STATUS status) { - tBTM_SEC_DEV_REC* p_dev_rec = nullptr; - uint8_t old_sec_state; - log::info("btm_sec_rmt_name_request_complete for {}", p_bd_addr ? ADDRESS_TO_LOGGABLE_CSTR(*p_bd_addr) : "null"); @@ -2295,6 +2292,7 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, /* If remote name request failed, p_bd_addr is null and we need to search */ /* based on state assuming that we are doing 1 at a time */ + tBTM_SEC_DEV_REC* p_dev_rec = nullptr; if (p_bd_addr) p_dev_rec = btm_find_dev(*p_bd_addr); else { @@ -2327,7 +2325,7 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, return; } - old_sec_state = p_dev_rec->sec_rec.sec_state; + uint8_t old_sec_state = p_dev_rec->sec_rec.sec_state; if (status == HCI_SUCCESS) { log::debug( "Remote read request complete for known device pairing_state:{} " -- GitLab From 2ec3e72722c1f40b4ef2aece38248f376cc02ad7 Mon Sep 17 00:00:00 2001 From: William Escande Date: Mon, 17 Jun 2024 16:10:54 -0700 Subject: [PATCH 0044/1446] ServiceBluetoothRoboTest: move to test_current We cannot use module api when being a test because song does not allow us. Replacing the module only Setting.Global by hard copying the string into the code. Flag: TEST_ONLY Test: atest ServiceBluetoothRoboTest Bug: 347766369 Change-Id: Ib654c2a4c1bf6ff0827eb00b5d521a39fd3a3970 --- service/Android.bp | 2 +- service/src/BleScanSettingListener.kt | 7 +++++-- service/src/BleScanSettingListenerTest.kt | 5 +++-- .../android/server/bluetooth/BluetoothManagerService.java | 4 ++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/service/Android.bp b/service/Android.bp index 21aa8d4b504..389ca316c8d 100644 --- a/service/Android.bp +++ b/service/Android.bp @@ -224,7 +224,7 @@ android_robolectric_test { "framework-statsd.stubs.module_lib", ], - sdk_version: "module_current", + sdk_version: "test_current", upstream: true, test_suites: ["general-tests"], strict_mode: false, diff --git a/service/src/BleScanSettingListener.kt b/service/src/BleScanSettingListener.kt index c173f3af3b3..cc93a3eeba2 100644 --- a/service/src/BleScanSettingListener.kt +++ b/service/src/BleScanSettingListener.kt @@ -27,6 +27,9 @@ import android.provider.Settings private const val TAG = "BleScanSettingListener" object BleScanSettingListener { + // Must match Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE but cannot depend on the variable + const val BLE_SCAN_ALWAYS_AVAILABLE = "ble_scan_always_enabled" + @JvmStatic var isScanAllowed = false private set @@ -43,7 +46,7 @@ object BleScanSettingListener { val notifyForDescendants = false resolver.registerContentObserver( - Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE), + Settings.Global.getUriFor(BLE_SCAN_ALWAYS_AVAILABLE), notifyForDescendants, object : ContentObserver(Handler(looper)) { override fun onChange(selfChange: Boolean) { @@ -72,7 +75,7 @@ object BleScanSettingListener { */ private fun getScanSettingValue(resolver: ContentResolver): Boolean { try { - return Settings.Global.getInt(resolver, Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE) != 0 + return Settings.Global.getInt(resolver, BLE_SCAN_ALWAYS_AVAILABLE) != 0 } catch (e: Settings.SettingNotFoundException) { Log.i(TAG, "Settings not found. Default to false") return false diff --git a/service/src/BleScanSettingListenerTest.kt b/service/src/BleScanSettingListenerTest.kt index 82aba2c1385..39bd6046301 100644 --- a/service/src/BleScanSettingListenerTest.kt +++ b/service/src/BleScanSettingListenerTest.kt @@ -20,6 +20,7 @@ import android.content.Context import android.os.Looper import android.provider.Settings import androidx.test.core.app.ApplicationProvider +import com.android.server.bluetooth.BleScanSettingListener.BLE_SCAN_ALWAYS_AVAILABLE import com.android.server.bluetooth.BleScanSettingListener.initialize import com.android.server.bluetooth.BleScanSettingListener.isScanAllowed import com.google.common.truth.Truth.assertThat @@ -48,12 +49,12 @@ class BleScanSettingListenerTest { } private fun enableSetting() { - Settings.Global.putInt(resolver, Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 1) + Settings.Global.putInt(resolver, BLE_SCAN_ALWAYS_AVAILABLE, 1) shadowOf(looper).idle() } private fun disableSetting() { - Settings.Global.putInt(resolver, Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0) + Settings.Global.putInt(resolver, BLE_SCAN_ALWAYS_AVAILABLE, 0) shadowOf(looper).idle() } diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java index 134463b726e..c20b458b330 100644 --- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java +++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java @@ -905,7 +905,7 @@ class BluetoothManagerService { } try { return Settings.Global.getInt( - mContentResolver, Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE) + mContentResolver, BleScanSettingListener.BLE_SCAN_ALWAYS_AVAILABLE) != 0; } catch (SettingNotFoundException e) { // The settings is considered as false by default. @@ -956,7 +956,7 @@ class BluetoothManagerService { }; mContentResolver.registerContentObserver( - Settings.Global.getUriFor(Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE), + Settings.Global.getUriFor(BleScanSettingListener.BLE_SCAN_ALWAYS_AVAILABLE), false, contentObserver); } -- GitLab From 6e4d5693c15e8cbecb2dfc0dd5bcde1d8e0d2653 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Fri, 14 Jun 2024 09:04:41 -0700 Subject: [PATCH 0045/1446] Flag: Remove rnr_present_during_service_discovery Bug: 321809163 Test: m . Change-Id: Idb7a0f81f6990b871e58a41f0edbbe8495e7c0a9 --- flags/rnr.aconfig | 7 ------- system/btif/src/btif_dm.cc | 8 ++------ system/btif/test/btif_dm_test.cc | 6 +----- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/flags/rnr.aconfig b/flags/rnr.aconfig index aa1eb7c39d3..7ced98342cf 100644 --- a/flags/rnr.aconfig +++ b/flags/rnr.aconfig @@ -1,13 +1,6 @@ package: "com.android.bluetooth.flags" container: "com.android.btservices" -flag { - name: "rnr_present_during_service_discovery" - namespace: "bluetooth" - description: "Present RNR result during service discovery" - bug: "321809163" -} - flag { name: "rnr_reset_state_at_cancel" namespace: "bluetooth" diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index fee33250302..f3c8b474ed5 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -2021,12 +2021,8 @@ static void btif_on_name_read(RawAddress bd_addr, tHCI_ERROR_CODE hci_status, // Differentiate between merged callbacks if (!during_device_search // New fix after refactor, this callback is needed for the fix to work - && - !com::android::bluetooth::flags::separate_service_and_device_discovery() - // Original fix, this callback should not be called if RNR should not be - // called - && - !com::android::bluetooth::flags::rnr_present_during_service_discovery()) { + && !com::android::bluetooth::flags:: + separate_service_and_device_discovery()) { log::info("Skipping name read event - called on bad callback."); return; } diff --git a/system/btif/test/btif_dm_test.cc b/system/btif/test/btif_dm_test.cc index 55545345f3a..c2210650e45 100644 --- a/system/btif/test/btif_dm_test.cc +++ b/system/btif/test/btif_dm_test.cc @@ -155,12 +155,8 @@ class BtifDmWithStackTest : public BtifDmTest { bluetooth::ModuleList modules_; }; -#define MY_PACKAGE com::android::bluetooth::flags - TEST_F_WITH_FLAGS(BtifDmWithStackTest, - btif_dm_search_services_evt__BTA_DM_NAME_READ_EVT, - REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG( - MY_PACKAGE, rnr_present_during_service_discovery))) { + btif_dm_search_services_evt__BTA_DM_NAME_READ_EVT) { static struct { bt_status_t status; RawAddress bd_addr; -- GitLab From cab59faa105464718b8030947b6712c236705983 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Tue, 4 Jun 2024 15:06:42 -0700 Subject: [PATCH 0046/1446] Class-enumify stack::l2cap::tL2CAP_DW_RESULT Bug: 344991872 Test: m . Flag: EXEMPT, Mechanical Refactor Change-Id: I925537804979745d42b47d081130817097322ba6 --- system/main/shim/l2c_api.h | 13 +++---- system/stack/arbiter/acl_arbiter.cc | 2 +- system/stack/avct/avct_bcb_act.cc | 6 ++-- system/stack/avct/avct_lcb_act.cc | 9 +++-- system/stack/bnep/bnep_main.cc | 3 +- system/stack/bnep/bnep_utils.cc | 3 +- system/stack/fuzzers/avrc_fuzzer.cc | 2 +- system/stack/fuzzers/bnep_fuzzer.cc | 2 +- system/stack/fuzzers/gatt_fuzzer.cc | 4 +-- system/stack/fuzzers/sdp_fuzzer.cc | 2 +- system/stack/fuzzers/smp_fuzzer.cc | 2 +- system/stack/gap/gap_conn.cc | 4 +-- system/stack/gatt/att_protocol.cc | 4 +-- system/stack/hid/hidd_conn.cc | 4 +-- system/stack/hid/hidh_conn.cc | 2 +- system/stack/include/l2c_api.h | 17 ++++----- system/stack/l2cap/l2c_api.cc | 29 +++++++-------- system/stack/l2cap/l2c_main.cc | 19 +++++----- system/stack/rfcomm/rfc_ts_frames.cc | 3 +- system/stack/rfcomm/rfc_utils.cc | 2 +- system/stack/sdp/sdp_discovery.cc | 9 +++-- system/stack/sdp/sdp_server.cc | 9 +++-- system/stack/sdp/sdp_utils.cc | 3 +- system/stack/smp/smp_utils.cc | 4 +-- system/stack/test/rfcomm/stack_rfcomm_test.cc | 36 +++++++++---------- system/stack/test/sdp/stack_sdp_parse_test.cc | 2 +- system/stack/test/sdp/stack_sdp_test.cc | 2 +- system/stack/test/sdp/stack_sdp_utils_test.cc | 2 +- system/test/mock/mock_stack_l2cap_api.h | 6 ++-- system/test/mock/mock_stack_l2cap_main.cc | 2 +- 30 files changed, 113 insertions(+), 94 deletions(-) diff --git a/system/main/shim/l2c_api.h b/system/main/shim/l2c_api.h index 88bd3bcd4f7..7f359cafef7 100644 --- a/system/main/shim/l2c_api.h +++ b/system/main/shim/l2c_api.h @@ -216,10 +216,11 @@ bool L2CA_DisconnectLECocReq(uint16_t cid); * * Description Higher layers call this function to write data. * - * Returns L2CAP_DW_SUCCESS, if data accepted, else false - * L2CAP_DW_CONGESTED, if data accepted and the channel is - * congested - * L2CAP_DW_FAILED, if error + * Returns tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS, if data accepted, else + * false + * tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED, if data accepted + * and the channel is congested + * tL2CAP_DW_RESULT::L2CAP_DW_FAILED, if error * ******************************************************************************/ uint8_t L2CA_DataWrite(uint16_t cid, BT_HDR* p_data); @@ -354,8 +355,8 @@ bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& bd_addr); * BD Address of remote * Pointer to buffer of type BT_HDR * - * Return value L2CAP_DW_SUCCESS, if data accepted - * L2CAP_DW_FAILED, if error + * Return value tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS, if data accepted + * tL2CAP_DW_RESULT::L2CAP_DW_FAILED, if error * ******************************************************************************/ uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda, diff --git a/system/stack/arbiter/acl_arbiter.cc b/system/stack/arbiter/acl_arbiter.cc index ff3a671eb14..c7f43271cc7 100644 --- a/system/stack/arbiter/acl_arbiter.cc +++ b/system/stack/arbiter/acl_arbiter.cc @@ -117,7 +117,7 @@ void AclArbiter::SendPacketToPeer(uint8_t tcb_idx, p_buf->offset = L2CAP_MIN_OFFSET; p_buf->len = buffer.size(); if (L2CA_SendFixedChnlData(L2CAP_ATT_CID, p_tcb->peer_bda, p_buf) != - L2CAP_DW_SUCCESS) { + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to send L2CAP data peer:{} fixed_cid:{} len:{}", p_tcb->peer_bda, L2CAP_ATT_CID, p_buf->len); } diff --git a/system/stack/avct/avct_bcb_act.cc b/system/stack/avct/avct_bcb_act.cc index c4ad4319043..2ef6eb41240 100644 --- a/system/stack/avct/avct_bcb_act.cc +++ b/system/stack/avct/avct_bcb_act.cc @@ -476,7 +476,8 @@ void avct_bcb_send_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) { p_buf->layer_specific = AVCT_DATA_BROWSE; /* send message to L2CAP */ - if (L2CA_DataWrite(p_bcb->ch_lcid, p_buf) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_bcb->ch_lcid, p_buf) != + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{}", p_bcb->peer_addr, p_bcb->ch_lcid); } @@ -582,7 +583,8 @@ void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) { AVCT_BUILD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ); UINT16_TO_BE_STREAM(p, pid); p_buf->layer_specific = AVCT_DATA_BROWSE; - if (L2CA_DataWrite(p_bcb->ch_lcid, p_buf) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_bcb->ch_lcid, p_buf) != + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{}", p_bcb->peer_addr, p_bcb->ch_lcid); } diff --git a/system/stack/avct/avct_lcb_act.cc b/system/stack/avct/avct_lcb_act.cc index b035721b0d4..981f9cc9ec0 100644 --- a/system/stack/avct/avct_lcb_act.cc +++ b/system/stack/avct/avct_lcb_act.cc @@ -507,7 +507,8 @@ void avct_lcb_cong_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { if (!p_lcb->cong && !fixed_queue_is_empty(p_lcb->tx_q)) { while (!p_lcb->cong && (p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_lcb->tx_q)) != NULL) { - if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == L2CAP_DW_CONGESTED) { + if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == + tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED) { p_lcb->cong = true; } } @@ -619,7 +620,8 @@ void avct_lcb_send_msg(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { /* send message to L2CAP */ else { - if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == L2CAP_DW_CONGESTED) { + if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == + tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED) { p_lcb->cong = true; } } @@ -723,7 +725,8 @@ void avct_lcb_msg_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { p = (uint8_t*)(p_buf + 1) + p_buf->offset; AVCT_BUILD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ); UINT16_TO_BE_STREAM(p, pid); - if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) != + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_lcb->peer_addr, p_lcb->ch_lcid, p_buf->len); } diff --git a/system/stack/bnep/bnep_main.cc b/system/stack/bnep/bnep_main.cc index e761f129a90..1a269d9228b 100644 --- a/system/stack/bnep/bnep_main.cc +++ b/system/stack/bnep/bnep_main.cc @@ -304,7 +304,8 @@ static void bnep_congestion_ind(uint16_t l2cap_cid, bool is_congested) { if (!p_buf) break; - if (L2CA_DataWrite(l2cap_cid, p_buf) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(l2cap_cid, p_buf) != + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_bcb->rem_bda, l2cap_cid, p_buf->len); } diff --git a/system/stack/bnep/bnep_utils.cc b/system/stack/bnep/bnep_utils.cc index 7129ccf690d..113937c4930 100644 --- a/system/stack/bnep/bnep_utils.cc +++ b/system/stack/bnep/bnep_utils.cc @@ -415,7 +415,8 @@ void bnepu_check_send_packet(tBNEP_CONN* p_bcb, BT_HDR* p_buf) { fixed_queue_enqueue(p_bcb->xmit_q, p_buf); } } else { - if (L2CA_DataWrite(p_bcb->l2cap_cid, p_buf) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_bcb->l2cap_cid, p_buf) != + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_bcb->rem_bda, p_bcb->l2cap_cid, p_buf->len); } diff --git a/system/stack/fuzzers/avrc_fuzzer.cc b/system/stack/fuzzers/avrc_fuzzer.cc index dfffe6a1816..387e427f13d 100644 --- a/system/stack/fuzzers/avrc_fuzzer.cc +++ b/system/stack/fuzzers/avrc_fuzzer.cc @@ -62,7 +62,7 @@ class FakeBtStack { log::assert_that(cid == kDummyCid, "assert failed: cid == kDummyCid"); ConsumeData((const uint8_t*)hdr, hdr->offset + hdr->len); osi_free(hdr); - return L2CAP_DW_SUCCESS; + return tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t cid) { log::assert_that(cid == kDummyCid, "assert failed: cid == kDummyCid"); diff --git a/system/stack/fuzzers/bnep_fuzzer.cc b/system/stack/fuzzers/bnep_fuzzer.cc index 99edaa4d13f..e7f396d71f1 100644 --- a/system/stack/fuzzers/bnep_fuzzer.cc +++ b/system/stack/fuzzers/bnep_fuzzer.cc @@ -56,7 +56,7 @@ class FakeBtStack { bluetooth::log::assert_that(cid == kDummyCid, "assert failed: cid == kDummyCid"); osi_free(p_data); - return L2CAP_DW_SUCCESS; + return tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t cid) { bluetooth::log::assert_that(cid == kDummyCid, diff --git a/system/stack/fuzzers/gatt_fuzzer.cc b/system/stack/fuzzers/gatt_fuzzer.cc index 8691f7689b2..63a086443d6 100644 --- a/system/stack/fuzzers/gatt_fuzzer.cc +++ b/system/stack/fuzzers/gatt_fuzzer.cc @@ -86,7 +86,7 @@ class FakeBtStack { test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t lcid, BT_HDR* hdr) { osi_free(hdr); - return L2CAP_DW_SUCCESS; + return tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t) { return true; @@ -94,7 +94,7 @@ class FakeBtStack { test::mock::stack_l2cap_api::L2CA_SendFixedChnlData.body = [](uint16_t cid, const RawAddress& addr, BT_HDR* hdr) { osi_free(hdr); - return L2CAP_DW_SUCCESS; + return tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS; }; test::mock::stack_l2cap_api::L2CA_RegisterFixedChannel.body = [](uint16_t fixed_cid, tL2CAP_FIXED_CHNL_REG* p_freg) { diff --git a/system/stack/fuzzers/sdp_fuzzer.cc b/system/stack/fuzzers/sdp_fuzzer.cc index 8f7c2d3dcf0..9a03b5b28f6 100644 --- a/system/stack/fuzzers/sdp_fuzzer.cc +++ b/system/stack/fuzzers/sdp_fuzzer.cc @@ -91,7 +91,7 @@ class FakeL2cap { [](uint16_t cid, BT_HDR* p_data) -> tL2CAP_DW_RESULT { auto len = p_data->len; osi_free(p_data); - return L2CAP_DW_SUCCESS; + return tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t lcid) { return true; diff --git a/system/stack/fuzzers/smp_fuzzer.cc b/system/stack/fuzzers/smp_fuzzer.cc index 7a80902a96d..31e030c2496 100644 --- a/system/stack/fuzzers/smp_fuzzer.cc +++ b/system/stack/fuzzers/smp_fuzzer.cc @@ -94,7 +94,7 @@ class FakeBtStack { test::mock::stack_l2cap_api::L2CA_SendFixedChnlData.body = [](uint16_t cid, const RawAddress& addr, BT_HDR* hdr) { osi_free(hdr); - return L2CAP_DW_SUCCESS; + return tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS; }; test::mock::stack_l2cap_api::L2CA_RegisterFixedChannel.body = [](uint16_t fixed_cid, tL2CAP_FIXED_CHNL_REG* p_freg) { diff --git a/system/stack/gap/gap_conn.cc b/system/stack/gap/gap_conn.cc index fe0164bde1c..8e379c4c167 100644 --- a/system/stack/gap/gap_conn.cc +++ b/system/stack/gap/gap_conn.cc @@ -441,10 +441,10 @@ static bool gap_try_write_queued_data(tGAP_CCB* p_ccb) { status = L2CA_DataWrite(p_ccb->connection_id, p_buf); } - if (status == L2CAP_DW_CONGESTED) { + if (status == tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED) { p_ccb->is_congested = true; return true; - } else if (status != L2CAP_DW_SUCCESS) + } else if (status != tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) return false; } return true; diff --git a/system/stack/gatt/att_protocol.cc b/system/stack/gatt/att_protocol.cc index 9fcb2c9b43c..4294c149b77 100644 --- a/system/stack/gatt/att_protocol.cc +++ b/system/stack/gatt/att_protocol.cc @@ -383,10 +383,10 @@ tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB& tcb, uint16_t lcid, l2cap_ret = L2CA_DataWrite(lcid, p_toL2CAP); } - if (l2cap_ret == L2CAP_DW_FAILED) { + if (l2cap_ret == tL2CAP_DW_RESULT::L2CAP_DW_FAILED) { log::error("failed to write data to L2CAP"); return GATT_INTERNAL_ERROR; - } else if (l2cap_ret == L2CAP_DW_CONGESTED) { + } else if (l2cap_ret == tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED) { log::verbose("ATT congested, message accepted"); return GATT_CONGESTED; } diff --git a/system/stack/hid/hidd_conn.cc b/system/stack/hid/hidd_conn.cc index c6debe12f13..95fce1df1eb 100644 --- a/system/stack/hid/hidd_conn.cc +++ b/system/stack/hid/hidd_conn.cc @@ -89,7 +89,7 @@ static void hidd_check_config_done() { // send outstanding data on intr if (hd_cb.pending_data) { if (L2CA_DataWrite(p_hcon->intr_cid, hd_cb.pending_data) != - L2CAP_DW_SUCCESS) { + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data cid:{} len:{}", p_hcon->intr_cid, hd_cb.pending_data->len); } @@ -822,7 +822,7 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, log::verbose("report sent"); - if (L2CA_DataWrite(cid, p_buf) == L2CAP_DW_FAILED) { + if (L2CA_DataWrite(cid, p_buf) == tL2CAP_DW_RESULT::L2CAP_DW_FAILED) { log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDD_ERR_CONGESTED_AT_DATA_WRITE, 1); diff --git a/system/stack/hid/hidh_conn.cc b/system/stack/hid/hidh_conn.cc index e3d90fe09c9..3e8699be1bc 100644 --- a/system/stack/hid/hidh_conn.cc +++ b/system/stack/hid/hidh_conn.cc @@ -848,7 +848,7 @@ tHID_STATUS hidh_conn_snd_data(uint8_t dhandle, uint8_t trans_type, /* Send the buffer through L2CAP */ if ((p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) || - (L2CA_DataWrite(cid, p_buf) == L2CAP_DW_FAILED)) { + (L2CA_DataWrite(cid, p_buf) == tL2CAP_DW_RESULT::L2CAP_DW_FAILED)) { log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDH_ERR_CONGESTED_AT_SEND_DATA, 1); diff --git a/system/stack/include/l2c_api.h b/system/stack/include/l2c_api.h index 855d0d7da6c..ed45627fbae 100644 --- a/system/stack/include/l2c_api.h +++ b/system/stack/include/l2c_api.h @@ -52,11 +52,11 @@ #define L2CAP_FCS_LENGTH 2 /* result code for L2CA_DataWrite() */ -typedef enum : uint8_t { +enum class tL2CAP_DW_RESULT : uint8_t { L2CAP_DW_FAILED = 0, L2CAP_DW_SUCCESS = 1, L2CAP_DW_CONGESTED = 2, -} tL2CAP_DW_RESULT; +}; /* Values for priority parameter to L2CA_SetAclPriority */ typedef enum : uint8_t { @@ -578,10 +578,11 @@ void L2CA_DeregisterLECoc(uint16_t psm); * * Description Higher layers call this function to write data. * - * Returns L2CAP_DW_SUCCESS, if data accepted, else false - * L2CAP_DW_CONGESTED, if data accepted and the channel is - * congested - * L2CAP_DW_FAILED, if error + * Returns tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS, if data accepted, else + * false + * tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED, if data accepted and + * the channel is congested + * tL2CAP_DW_RESULT::L2CAP_DW_FAILED, if error * ******************************************************************************/ [[nodiscard]] tL2CAP_DW_RESULT L2CA_DataWrite(uint16_t cid, BT_HDR* p_data); @@ -806,8 +807,8 @@ typedef struct { * BD Address of remote * Pointer to buffer of type BT_HDR * - * Return value L2CAP_DW_SUCCESS, if data accepted - * L2CAP_DW_FAILED, if error + * Return value tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS, if data accepted + * tL2CAP_DW_RESULT::L2CAP_DW_FAILED, if error * ******************************************************************************/ [[nodiscard]] tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, diff --git a/system/stack/l2cap/l2c_api.cc b/system/stack/l2cap/l2c_api.cc index f43c139c6af..0befad885c0 100644 --- a/system/stack/l2cap/l2c_api.cc +++ b/system/stack/l2cap/l2c_api.cc @@ -1283,8 +1283,8 @@ bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& rem_bda) { * BD Address of remote * Pointer to buffer of type BT_HDR * - * Return value L2CAP_DW_SUCCESS, if data accepted - * L2CAP_DW_FAILED, if error + * Return value tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS, if data accepted + * tL2CAP_DW_RESULT::L2CAP_DW_FAILED, if error * ******************************************************************************/ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, @@ -1302,13 +1302,13 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, NULL)) { log::warn("No service registered or invalid CID: 0x{:04x}", fixed_cid); osi_free(p_buf); - return (L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); } if (!BTM_IsDeviceUp()) { log::warn("Controller is not ready CID: 0x{:04x}", fixed_cid); osi_free(p_buf); - return (L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); } p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, transport); @@ -1317,7 +1317,7 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, log::warn("Link is disconnecting or does not exist CID: 0x{:04x}", fixed_cid); osi_free(p_buf); - return (L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); } tL2C_BLE_FIXED_CHNLS_MASK peer_channel_mask; @@ -1331,7 +1331,7 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, if ((peer_channel_mask & (1 << fixed_cid)) == 0) { log::warn("Peer does not support fixed channel CID: 0x{:04x}", fixed_cid); osi_free(p_buf); - return (L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); } p_buf->event = 0; @@ -1341,7 +1341,7 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, if (!l2cu_initialize_fixed_ccb(p_lcb, fixed_cid)) { log::warn("No channel control block found for CID: 0x{:4x}", fixed_cid); osi_free(p_buf); - return (L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); } } @@ -1355,7 +1355,7 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, ->xmit_hold_q), p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->buff_quota); osi_free(p_buf); - return (L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); } log::debug("Enqueued data for CID: 0x{:04x} len:{}", fixed_cid, p_buf->len); @@ -1373,10 +1373,10 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent) { log::debug("Link congested for CID: 0x{:04x}", fixed_cid); - return (L2CAP_DW_CONGESTED); + return (tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED); } - return (L2CAP_DW_SUCCESS); + return (tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS); } /******************************************************************************* @@ -1496,10 +1496,11 @@ bool L2CA_MarkLeLinkAsActive(const RawAddress& rem_bda) { * * Description Higher layers call this function to write data. * - * Returns L2CAP_DW_SUCCESS, if data accepted, else false - * L2CAP_DW_CONGESTED, if data accepted and the channel is - * congested - * L2CAP_DW_FAILED, if error + * Returns tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS, if data accepted, else + * false + * tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED, if data accepted + * and the channel is congested + * tL2CAP_DW_RESULT::L2CAP_DW_FAILED, if error * ******************************************************************************/ tL2CAP_DW_RESULT L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) { diff --git a/system/stack/l2cap/l2c_main.cc b/system/stack/l2cap/l2c_main.cc index dd17a5f8412..7fe9ec19316 100644 --- a/system/stack/l2cap/l2c_main.cc +++ b/system/stack/l2cap/l2c_main.cc @@ -900,10 +900,11 @@ void l2c_lcb_timer_timeout(void* data) { * * Description API functions call this function to write data. * - * Returns L2CAP_DW_SUCCESS, if data accepted, else false - * L2CAP_DW_CONGESTED, if data accepted and the channel is - * congested - * L2CAP_DW_FAILED, if error + * Returns tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS, if data accepted, + * else false + * tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED, if data accepted + * and the channel is congested + * tL2CAP_DW_RESULT::L2CAP_DW_FAILED, if error * ******************************************************************************/ tL2CAP_DW_RESULT l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flags) { @@ -912,7 +913,7 @@ tL2CAP_DW_RESULT l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flags) { if (!p_ccb) { log::warn("L2CAP - no CCB for L2CA_DataWrite, CID: {}", cid); osi_free(p_data); - return (L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); } /* Sending message bigger than mtu size of peer is a violation of protocol */ @@ -929,7 +930,7 @@ tL2CAP_DW_RESULT l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flags) { "size: len={} mtu={}", cid, p_data->len, mtu); osi_free(p_data); - return (L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); } /* channel based, packet based flushable or non-flushable */ @@ -944,12 +945,12 @@ tL2CAP_DW_RESULT l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flags) { p_ccb->buff_quota); osi_free(p_data); - return (L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); } l2c_csm_execute(p_ccb, L2CEVT_L2CA_DATA_WRITE, p_data); - if (p_ccb->cong_sent) return (L2CAP_DW_CONGESTED); + if (p_ccb->cong_sent) return (tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED); - return (L2CAP_DW_SUCCESS); + return (tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS); } diff --git a/system/stack/rfcomm/rfc_ts_frames.cc b/system/stack/rfcomm/rfc_ts_frames.cc index dd20e82c0d2..acc756c5840 100644 --- a/system/stack/rfcomm/rfc_ts_frames.cc +++ b/system/stack/rfcomm/rfc_ts_frames.cc @@ -201,7 +201,8 @@ void rfc_send_buf_uih(tRFC_MCB* p_mcb, uint8_t dlci, BT_HDR* p_buf) { if (dlci == RFCOMM_MX_DLCI) { rfc_check_send_cmd(p_mcb, p_buf); } else { - if (L2CA_DataWrite(p_mcb->lcid, p_buf) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_mcb->lcid, p_buf) != + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_mcb->bd_addr, p_mcb->lcid, p_buf->len); } diff --git a/system/stack/rfcomm/rfc_utils.cc b/system/stack/rfcomm/rfc_utils.cc index ccb21a82cb8..0a3214400f3 100644 --- a/system/stack/rfcomm/rfc_utils.cc +++ b/system/stack/rfcomm/rfc_utils.cc @@ -426,7 +426,7 @@ void rfc_check_send_cmd(tRFC_MCB* p_mcb, BT_HDR* p_buf) { while (!p_mcb->l2cap_congested) { BT_HDR* p = (BT_HDR*)fixed_queue_try_dequeue(p_mcb->cmd_q); if (p == NULL) break; - if (L2CA_DataWrite(p_mcb->lcid, p) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_mcb->lcid, p) != tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_mcb->bd_addr, p_mcb->lcid, p->len); } diff --git a/system/stack/sdp/sdp_discovery.cc b/system/stack/sdp/sdp_discovery.cc index b1166290e7f..11c8f389f5f 100644 --- a/system/stack/sdp/sdp_discovery.cc +++ b/system/stack/sdp/sdp_discovery.cc @@ -177,7 +177,8 @@ static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len, /* Set the length of the SDP data in the buffer */ p_cmd->len = (uint16_t)(p - p_start); - if (L2CA_DataWrite(p_ccb->connection_id, p_cmd) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_ccb->connection_id, p_cmd) != + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, p_ccb->connection_id, p_cmd->len); } @@ -687,7 +688,8 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, /* Set the length of the SDP data in the buffer */ p_msg->len = p - p_start; - if (L2CA_DataWrite(p_ccb->connection_id, p_msg) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_ccb->connection_id, p_msg) != + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, p_ccb->connection_id, p_msg->len); } @@ -861,7 +863,8 @@ static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, /* Set the length of the SDP data in the buffer */ p_msg->len = (uint16_t)(p - p_start); - if (L2CA_DataWrite(p_ccb->connection_id, p_msg) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_ccb->connection_id, p_msg) != + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, p_ccb->connection_id, p_msg->len); } diff --git a/system/stack/sdp/sdp_server.cc b/system/stack/sdp/sdp_server.cc index 0b2012e57c9..3902991645f 100644 --- a/system/stack/sdp/sdp_server.cc +++ b/system/stack/sdp/sdp_server.cc @@ -303,7 +303,8 @@ static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num, p_buf->len = p_rsp - p_rsp_start; /* Send the buffer through L2CAP */ - if (L2CA_DataWrite(p_ccb->connection_id, p_buf) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_ccb->connection_id, p_buf) != + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, p_ccb->connection_id, p_buf->len); } @@ -701,7 +702,8 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, p_buf->len = p_rsp - p_rsp_start; /* Send the buffer through L2CAP */ - if (L2CA_DataWrite(p_ccb->connection_id, p_buf) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_ccb->connection_id, p_buf) != + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, p_ccb->connection_id, p_buf->len); } @@ -1179,7 +1181,8 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, p_buf->len = p_rsp - p_rsp_start; /* Send the buffer through L2CAP */ - if (L2CA_DataWrite(p_ccb->connection_id, p_buf) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_ccb->connection_id, p_buf) != + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, p_ccb->connection_id, p_buf->len); } diff --git a/system/stack/sdp/sdp_utils.cc b/system/stack/sdp/sdp_utils.cc index a9b1d29ad8f..d22148f7f7c 100644 --- a/system/stack/sdp/sdp_utils.cc +++ b/system/stack/sdp/sdp_utils.cc @@ -739,7 +739,8 @@ void sdpu_build_n_send_error(tCONN_CB* p_ccb, uint16_t trans_num, p_buf->len = p_rsp - p_rsp_start; /* Send the buffer through L2CAP */ - if (L2CA_DataWrite(p_ccb->connection_id, p_buf) != L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_ccb->connection_id, p_buf) != + tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { log::warn("Unable to write L2CAP data cid:{}", p_ccb->connection_id); } } diff --git a/system/stack/smp/smp_utils.cc b/system/stack/smp/smp_utils.cc index 60cd2310dc3..eb586f32ff9 100644 --- a/system/stack/smp/smp_utils.cc +++ b/system/stack/smp/smp_utils.cc @@ -368,7 +368,7 @@ bool smp_send_msg_to_L2CAP(const RawAddress& rem_bda, BT_HDR* p_toL2CAP) { /* Unacked needs to be incremented before calling SendFixedChnlData */ smp_cb.total_tx_unacked++; l2cap_ret = L2CA_SendFixedChnlData(fixed_cid, rem_bda, p_toL2CAP); - if (l2cap_ret == L2CAP_DW_FAILED) { + if (l2cap_ret == tL2CAP_DW_RESULT::L2CAP_DW_FAILED) { smp_cb.total_tx_unacked--; log::error("SMP failed to pass msg to L2CAP"); return false; @@ -378,7 +378,7 @@ bool smp_send_msg_to_L2CAP(const RawAddress& rem_bda, BT_HDR* p_toL2CAP) { } l2cap_ret = L2CA_SendFixedChnlData(fixed_cid, rem_bda, p_toL2CAP); - if (l2cap_ret == L2CAP_DW_FAILED) { + if (l2cap_ret == tL2CAP_DW_RESULT::L2CAP_DW_FAILED) { log::error("SMP failed to pass msg to L2CAP"); return false; } else { diff --git a/system/stack/test/rfcomm/stack_rfcomm_test.cc b/system/stack/test/rfcomm/stack_rfcomm_test.cc index a0c417605cf..0a54a2f5990 100644 --- a/system/stack/test/rfcomm/stack_rfcomm_test.cc +++ b/system/stack/test/rfcomm/stack_rfcomm_test.cc @@ -179,7 +179,7 @@ class StackRfcommTest : public Test { BT_HDR* ua_channel_0 = AllocateWrappedOutgoingL2capAclPacket( CreateQuickUaPacket(RFCOMM_MX_DLCI, lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(ua_channel_0))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); // Packet should be freed by RFCOMM l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, sabm_channel_0); osi_free(ua_channel_0); @@ -200,7 +200,7 @@ class StackRfcommTest : public Test { lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_pn_rsp_to_peer))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); // uih_pn_cmd_from_peer should be freed by this method l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_pn_cmd_from_peer); osi_free(uih_pn_rsp_to_peer); @@ -228,7 +228,7 @@ class StackRfcommTest : public Test { BT_HDR* ua_channel_dlci = AllocateWrappedOutgoingL2capAclPacket( CreateQuickUaPacket(GetDlci(false, scn), lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(ua_channel_dlci))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); ASSERT_TRUE(security_callback); security_callback(peer_addr, BT_TRANSPORT_BR_EDR, p_port, BTM_SUCCESS); osi_free(ua_channel_dlci); @@ -244,13 +244,13 @@ class StackRfcommTest : public Test { // We also have to do modem configuration ourself EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_msc_response_to_peer))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); BT_HDR* uih_msc_cmd_to_peer = AllocateWrappedOutgoingL2capAclPacket( CreateQuickMscPacket(false, GetDlci(false, scn), lcid, acl_handle, true, false, true, true, false, true)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_msc_cmd_to_peer))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); // uih_msc_cmd_from_peer should be freed by this method l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_cmd_from_peer); osi_free(uih_msc_response_to_peer); @@ -281,7 +281,7 @@ class StackRfcommTest : public Test { } else { EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_pn_channel_3))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); } ASSERT_EQ(RFCOMM_CreateConnectionWithSecurity(uuid, scn, false, mtu, peer_bd_addr, client_handle, @@ -317,7 +317,7 @@ class StackRfcommTest : public Test { BT_HDR* sabm_channel_0 = AllocateWrappedOutgoingL2capAclPacket( CreateQuickSabmPacket(RFCOMM_MX_DLCI, lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(sabm_channel_0))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); l2cap_appl_info_.pL2CA_ConfigInd_Cb(lcid, &cfg_req); osi_free(sabm_channel_0); } @@ -340,7 +340,7 @@ class StackRfcommTest : public Test { RFCOMM_K_MAX, lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_pn_channel_3))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, ua_channel_0); osi_free(uih_pn_channel_3); } @@ -367,7 +367,7 @@ class StackRfcommTest : public Test { BT_HDR* sabm_channel_3 = AllocateWrappedOutgoingL2capAclPacket( CreateQuickSabmPacket(GetDlci(false, scn), lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(sabm_channel_3))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); ASSERT_TRUE(security_callback); security_callback(peer_addr, BT_TRANSPORT_BR_EDR, p_port, BTM_SUCCESS); osi_free(sabm_channel_3); @@ -382,7 +382,7 @@ class StackRfcommTest : public Test { CreateQuickMscPacket(true, GetDlci(false, scn), lcid, acl_handle, true, false, true, true, false, true)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_msc_cmd))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); BT_HDR* ua_channel_3 = AllocateWrappedIncomingL2capAclPacket( CreateQuickUaPacket(GetDlci(false, scn), lcid, acl_handle)); l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, ua_channel_3); @@ -405,7 +405,7 @@ class StackRfcommTest : public Test { false, true, true, false, true)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_msc_response_to_peer))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_cmd_from_peer); osi_free(uih_msc_response_to_peer); } @@ -421,7 +421,7 @@ class StackRfcommTest : public Test { credits, message)); uint16_t transmitted_length = 0; EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(data_packet))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); ASSERT_EQ(PORT_WriteData(port_handle, message.data(), message.size(), &transmitted_length), PORT_SUCCESS); @@ -795,7 +795,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { BT_HDR* ua_channel_0 = AllocateWrappedOutgoingL2capAclPacket( CreateQuickUaPacket(RFCOMM_MX_DLCI, new_lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(ua_channel_0))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); // And immediately try to configure test_peer_scn BT_HDR* uih_pn_cmd_to_peer = AllocateWrappedOutgoingL2capAclPacket( CreateQuickPnPacket(false, GetDlci(true, test_peer_scn), true, test_mtu, @@ -803,7 +803,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { new_lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(uih_pn_cmd_to_peer))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); // Packet should be freed by this method l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, sabm_channel_0); osi_free(ua_channel_0); @@ -823,7 +823,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(uih_pn_rsp_to_peer))) .Times(1) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, uih_pn_cmd_from_peer); osi_free(uih_pn_rsp_to_peer); @@ -851,7 +851,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { AllocateWrappedOutgoingL2capAclPacket(CreateQuickUaPacket( GetDlci(false, test_server_scn), new_lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(ua_server_scn))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); // Callback should come from server port instead, client port will timeout // in 20 seconds EXPECT_CALL(rfcomm_callback_, @@ -870,13 +870,13 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { // MPX_CTRL Modem Status Response (MSC) EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(uih_msc_rsp_to_peer))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); BT_HDR* uih_msc_cmd_to_peer = AllocateWrappedOutgoingL2capAclPacket( CreateQuickMscPacket(false, GetDlci(false, test_server_scn), new_lcid, acl_handle, true, false, true, true, false, true)); EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(uih_msc_cmd_to_peer))) - .WillOnce(Return(L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, uih_msc_cmd_from_peer); osi_free(uih_msc_rsp_to_peer); osi_free(uih_msc_cmd_to_peer); diff --git a/system/stack/test/sdp/stack_sdp_parse_test.cc b/system/stack/test/sdp/stack_sdp_parse_test.cc index 0d5f339d9de..5822a596719 100644 --- a/system/stack/test/sdp/stack_sdp_parse_test.cc +++ b/system/stack/test/sdp/stack_sdp_parse_test.cc @@ -63,7 +63,7 @@ class StackSdpParserWithMocksTest : public ::testing::Test { test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t /* cid */, BT_HDR* p_data) { osi_free_and_reset((void**)&p_data); - return L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t /* cid */) { return true; }; diff --git a/system/stack/test/sdp/stack_sdp_test.cc b/system/stack/test/sdp/stack_sdp_test.cc index aa3db3c9eb4..ffbf325b8ed 100644 --- a/system/stack/test/sdp/stack_sdp_test.cc +++ b/system/stack/test/sdp/stack_sdp_test.cc @@ -52,7 +52,7 @@ class StackSdpWithMocksTest : public ::testing::Test { test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t /* cid */, BT_HDR* p_data) -> tL2CAP_DW_RESULT { osi_free_and_reset((void**)&p_data); - return L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t /* cid */) { return true; }; diff --git a/system/stack/test/sdp/stack_sdp_utils_test.cc b/system/stack/test/sdp/stack_sdp_utils_test.cc index 21ddc87fd38..db1c224f968 100644 --- a/system/stack/test/sdp/stack_sdp_utils_test.cc +++ b/system/stack/test/sdp/stack_sdp_utils_test.cc @@ -257,7 +257,7 @@ class StackSdpMockAndFakeTest : public ::testing::Test { test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t /* cid */, BT_HDR* p_data) -> tL2CAP_DW_RESULT { osi_free_and_reset((void**)&p_data); - return L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t /* cid */) { return true; }; diff --git a/system/test/mock/mock_stack_l2cap_api.h b/system/test/mock/mock_stack_l2cap_api.h index f4249ef2444..c383e83c15b 100644 --- a/system/test/mock/mock_stack_l2cap_api.h +++ b/system/test/mock/mock_stack_l2cap_api.h @@ -379,7 +379,7 @@ struct L2CA_SendFixedChnlData { BT_HDR* p_buf)> body{[](uint16_t /* fixed_cid */, const RawAddress& /* rem_bda */, BT_HDR* /* p_buf */) -> tL2CAP_DW_RESULT { - return L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; }}; tL2CAP_DW_RESULT operator()(uint16_t fixed_cid, const RawAddress& rem_bda, BT_HDR* p_buf) { @@ -428,7 +428,7 @@ extern struct L2CA_MarkLeLinkAsActive L2CA_MarkLeLinkAsActive; struct L2CA_DataWrite { std::function body{ [](uint16_t /* cid */, BT_HDR* /* p_data */) -> tL2CAP_DW_RESULT { - return L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; }}; tL2CAP_DW_RESULT operator()(uint16_t cid, BT_HDR* p_data) { return body(cid, p_data); @@ -441,7 +441,7 @@ extern struct L2CA_DataWrite L2CA_DataWrite; struct L2CA_LECocDataWrite { std::function body{ [](uint16_t /* cid */, BT_HDR* /* p_data */) -> tL2CAP_DW_RESULT { - return L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; }}; tL2CAP_DW_RESULT operator()(uint16_t cid, BT_HDR* p_data) { return body(cid, p_data); diff --git a/system/test/mock/mock_stack_l2cap_main.cc b/system/test/mock/mock_stack_l2cap_main.cc index 68729ad4dee..98cb699ee55 100644 --- a/system/test/mock/mock_stack_l2cap_main.cc +++ b/system/test/mock/mock_stack_l2cap_main.cc @@ -27,7 +27,7 @@ tL2CAP_DW_RESULT l2c_data_write(uint16_t /* cid */, BT_HDR* /* p_data */, uint16_t /* flags */) { inc_func_call_count(__func__); - return L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; } void l2c_ccb_timer_timeout(void* /* data */) { inc_func_call_count(__func__); } void l2c_fcrb_ack_timer_timeout(void* /* data */) { -- GitLab From 64bd136471fc0fab5cfac80284a1c3074dc7f8d4 Mon Sep 17 00:00:00 2001 From: Charlie Boutier Date: Tue, 18 Jun 2024 00:19:45 +0000 Subject: [PATCH 0047/1446] ParingTests: Open OnPairing before any connections Bug: 319885398 Test: atest BumbleBluetoothTests FLAG: TEST_ONLY Change-Id: I180209aa753dffc9a41215b141cd5ee823b31a5a --- .../src/android/bluetooth/pairing/PairingTest.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java b/framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java index fa97c3bf606..d5002b63c5e 100644 --- a/framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java +++ b/framework/tests/bumble/src/android/bluetooth/pairing/PairingTest.java @@ -236,6 +236,11 @@ public class PairingTest { BluetoothDevice.ACTION_BOND_STATE_CHANGED, BluetoothDevice.ACTION_PAIRING_REQUEST); + StreamObserver pairingEventAnswerObserver = + mBumble.security() + .withDeadlineAfter(BOND_INTENT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS) + .onPairing(mPairingEventStreamObserver); + // Start SDP. This will create an ACL connection before the bonding starts. assertThat(mBumbleDevice.fetchUuidsWithSdp(BluetoothDevice.TRANSPORT_BREDR)).isTrue(); @@ -243,10 +248,6 @@ public class PairingTest { hasAction(BluetoothDevice.ACTION_ACL_CONNECTED), hasExtra(BluetoothDevice.EXTRA_DEVICE, mBumbleDevice)); - StreamObserver pairingEventAnswerObserver = - mBumble.security() - .withDeadlineAfter(BOND_INTENT_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS) - .onPairing(mPairingEventStreamObserver); assertThat(mBumbleDevice.createBond()).isTrue(); verifyIntentReceived( -- GitLab From 56953eaa5d86517c4beabc191f8c6c292359cf1a Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Mon, 17 Jun 2024 23:09:21 +0000 Subject: [PATCH 0048/1446] Add flag a2dp_aidl_encoding_interval Bug: 347781402 Bug: 336658618 Bug: 315241296 Test: m com.android.btservices Change-Id: I52b87207ecffe7c91da5af6cf1b73b02cd4a250f --- flags/a2dp.aconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/flags/a2dp.aconfig b/flags/a2dp.aconfig index ddb191b7d7b..08923296a05 100644 --- a/flags/a2dp.aconfig +++ b/flags/a2dp.aconfig @@ -85,3 +85,13 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "a2dp_aidl_encoding_interval" + namespace: "bluetooth" + description: "Configure the data interval in audio BT HAL's PcmConfig" + bug: "347781402" + metadata { + purpose: PURPOSE_BUGFIX + } +} -- GitLab From 163834d0d477f8545e95a37734878ebf3caab720 Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Mon, 17 Jun 2024 17:43:03 -0700 Subject: [PATCH 0049/1446] gdcert: Remove unused helper PySecurity GD cert security tests have been removed in Iccf2c497a7605be35c3ee2d3f8cd82d8d0c02ee1 Bug: 333555245 Test: None Flag: EXEMPT, dead code removal Change-Id: Ie68daaa7650dca87f38379dbcc725e99e18b58cd --- system/blueberry/tests/gd/cert/captures.py | 14 - .../blueberry/tests/gd/cert/py_le_security.py | 10 - system/blueberry/tests/gd/cert/py_security.py | 276 ------------------ 3 files changed, 300 deletions(-) delete mode 100644 system/blueberry/tests/gd/cert/py_security.py diff --git a/system/blueberry/tests/gd/cert/captures.py b/system/blueberry/tests/gd/cert/captures.py index 104f8df9182..7358ad1e706 100644 --- a/system/blueberry/tests/gd/cert/captures.py +++ b/system/blueberry/tests/gd/cert/captures.py @@ -17,7 +17,6 @@ from blueberry.tests.gd.cert.capture import Capture from blueberry.tests.gd.cert.matchers import HciMatchers from blueberry.tests.gd.cert.matchers import SecurityMatchers -from blueberry.facade.security.facade_pb2 import UiMsgType import hci_packets as hci @@ -93,16 +92,3 @@ class HciCaptures(object): def SimplePairingCompleteCapture(): return Capture(HciMatchers.EventWithCode(hci.EventCode.SIMPLE_PAIRING_COMPLETE), lambda packet: hci.Event.parse_all(packet.payload)) - - -class SecurityCaptures(object): - - @staticmethod - def DisplayPasskey(): - return Capture(SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PASSKEY), SecurityCaptures._extract_passkey) - - @staticmethod - def _extract_passkey(event): - if event is None: - return None - return event.numeric_value diff --git a/system/blueberry/tests/gd/cert/py_le_security.py b/system/blueberry/tests/gd/cert/py_le_security.py index 1055dd166d4..d33d2552681 100644 --- a/system/blueberry/tests/gd/cert/py_le_security.py +++ b/system/blueberry/tests/gd/cert/py_le_security.py @@ -16,7 +16,6 @@ import logging -from blueberry.tests.gd.cert.captures import SecurityCaptures from blueberry.tests.gd.cert.closable import Closable from blueberry.tests.gd.cert.closable import safeClose from blueberry.tests.gd.cert.event_stream import EventStream @@ -56,15 +55,6 @@ class PyLeSecurity(Closable): def get_advertising_callback_event_stream(self): return self._advertising_callback_event_stream - def wait_for_ui_event_passkey(self, timeout=timedelta(seconds=3)): - display_passkey_capture = SecurityCaptures.DisplayPasskey() - assertThat(self._ui_event_stream).emits(display_passkey_capture, timeout=timeout) - return display_passkey_capture.get() - - def wait_device_disconnect(self, address): - assertThat(self._helper_event_stream).emits( - SecurityMatchers.HelperMsg(HelperMsgType.DEVICE_DISCONNECTED, address)) - def SetLeAuthRequirements(self, *args, **kwargs): return self._device.security.SetLeAuthRequirements(LeAuthRequirementsMessage(*args, **kwargs)) diff --git a/system/blueberry/tests/gd/cert/py_security.py b/system/blueberry/tests/gd/cert/py_security.py deleted file mode 100644 index e8f62a80e53..00000000000 --- a/system/blueberry/tests/gd/cert/py_security.py +++ /dev/null @@ -1,276 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2020 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging - -from blueberry.tests.gd.cert.closable import Closable -from blueberry.tests.gd.cert.closable import safeClose -from blueberry.tests.gd.cert.event_stream import EventStream -from blueberry.tests.gd.cert.truth import assertThat -from blueberry.facade import common_pb2 as common -from google.protobuf import empty_pb2 as empty_proto - -from blueberry.facade.security.facade_pb2 import AuthenticationRequirements -from blueberry.facade.security.facade_pb2 import AuthenticationRequirementsMessage -from blueberry.facade.security.facade_pb2 import SecurityPolicyMessage -from blueberry.facade.security.facade_pb2 import IoCapabilities -from blueberry.facade.security.facade_pb2 import IoCapabilityMessage -from blueberry.facade.security.facade_pb2 import OobDataBondMessage -from blueberry.facade.security.facade_pb2 import OobDataMessage -from blueberry.facade.security.facade_pb2 import UiMsgType -from blueberry.facade.security.facade_pb2 import UiCallbackMsg -from blueberry.facade.security.facade_pb2 import UiCallbackType - - -class PySecurity(Closable): - """ - Abstraction for security tasks and GRPC calls - """ - - _io_capabilities_name_lookup = { - IoCapabilities.DISPLAY_ONLY: "DISPLAY_ONLY", - IoCapabilities.DISPLAY_YES_NO_IO_CAP: "DISPLAY_YES_NO_IO_CAP", - IoCapabilities.KEYBOARD_ONLY: "KEYBOARD_ONLY", - IoCapabilities.NO_INPUT_NO_OUTPUT: "NO_INPUT_NO_OUTPUT", - } - - _auth_reqs_name_lookup = { - AuthenticationRequirements.NO_BONDING: "NO_BONDING", - AuthenticationRequirements.NO_BONDING_MITM_PROTECTION: "NO_BONDING_MITM_PROTECTION", - AuthenticationRequirements.DEDICATED_BONDING: "DEDICATED_BONDING", - AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION: "DEDICATED_BONDING_MITM_PROTECTION", - AuthenticationRequirements.GENERAL_BONDING: "GENERAL_BONDING", - AuthenticationRequirements.GENERAL_BONDING_MITM_PROTECTION: "GENERAL_BONDING_MITM_PROTECTION", - } - - _ui_event_stream = None - _bond_event_stream = None - _oob_data_event_stream = None - - def __init__(self, device): - logging.info("DUT: Init") - self._device = device - self._device.wait_channel_ready() - self._ui_event_stream = EventStream(self._device.security.FetchUiEvents(empty_proto.Empty())) - self._bond_event_stream = EventStream(self._device.security.FetchBondEvents(empty_proto.Empty())) - self._enforce_security_policy_stream = EventStream( - self._device.security.FetchEnforceSecurityPolicyEvents(empty_proto.Empty())) - self._disconnect_event_stream = EventStream(self._device.security.FetchDisconnectEvents(empty_proto.Empty())) - self._oob_data_event_stream = EventStream( - self._device.security.FetchGetOutOfBandDataEvents(empty_proto.Empty())) - - def create_bond(self, address, type): - """ - Triggers stack under test to create bond - """ - logging.info("DUT: Creating bond to '%s' from '%s'" % (str(address), str(self._device.address))) - self._device.security.CreateBond( - common.BluetoothAddressWithType(address=common.BluetoothAddress(address=address), type=type)) - - def create_bond_out_of_band(self, address, type, p192_oob_data, p256_oob_data): - """ - Triggers stack under test to create bond using Out of Band method - """ - - logging.info("DUT: Creating OOB bond to '%s' from '%s'" % (str(address), str(self._device.address))) - - self._device.security.CreateBondOutOfBand( - OobDataBondMessage( - address=common.BluetoothAddressWithType(address=common.BluetoothAddress(address=address), type=type), - p192_data=OobDataMessage( - address=common.BluetoothAddressWithType( - address=common.BluetoothAddress(address=address), type=type), - confirmation_value=bytes(bytearray(p192_oob_data[0])), - random_value=bytes(bytearray(p192_oob_data[1]))), - p256_data=OobDataMessage( - address=common.BluetoothAddressWithType( - address=common.BluetoothAddress(address=address), type=type), - confirmation_value=bytes(bytearray(p256_oob_data[0])), - random_value=bytes(bytearray(p256_oob_data[1]))))) - - def remove_bond(self, address, type): - """ - Removes bond from stack under test - """ - self._device.security.RemoveBond( - common.BluetoothAddressWithType(address=common.BluetoothAddress(address=address), type=type)) - - def set_io_capabilities(self, io_capabilities): - """ - Set the IO Capabilities used for the DUT - """ - logging.info("DUT: setting IO Capabilities data to '%s'" % self._io_capabilities_name_lookup.get( - io_capabilities, "ERROR")) - self._device.security.SetIoCapability(IoCapabilityMessage(capability=io_capabilities)) - - def set_authentication_requirements(self, auth_reqs): - """ - Establish authentication requirements for the stack - """ - logging.info("DUT: setting Authentication Requirements data to '%s'" % self._auth_reqs_name_lookup.get( - auth_reqs, "ERROR")) - self._device.security.SetAuthenticationRequirements(AuthenticationRequirementsMessage(requirement=auth_reqs)) - - def __send_ui_callback(self, address, callback_type, b, uid, pin): - """ - Send a callback from the UI as if the user pressed a button on the dialog - """ - logging.info("DUT: Sending user input response uid: %d; response: %s" % (uid, b)) - self._device.security.SendUiCallback( - UiCallbackMsg( - message_type=callback_type, - boolean=b, - unique_id=uid, - pin=bytes(pin), - address=common.BluetoothAddressWithType( - address=common.BluetoothAddress(address=address), - type=common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS))) - - def enable_secure_simple_pairing(self): - """ - This is called when you want to enable SSP for testing - Since the stack under test already enables it by default - we do not need to do anything here for the time being - """ - pass - - def enable_secure_connections(self): - pass - - def accept_pairing(self, cert_address, reply_boolean): - """ - Here we pass, but in cert we perform pairing flow tasks. - This was added here in order to be more dynamic, but the stack - under test will handle the pairing flow. - """ - pass - - def accept_oob_pairing(self, cert_address, reply_boolean): - """ - Here we pass, but in cert we perform pairing flow tasks. - This was added here in order to be more dynamic, but the stack - under test will handle the pairing flow. - """ - pass - - def wait_for_passkey(self, cert_address): - """ - Respond to the UI event - """ - passkey = -1 - - def get_passkey(event): - if event.message_type == UiMsgType.DISPLAY_PASSKEY: - nonlocal passkey - passkey = event.numeric_value - return True - return False - - logging.info("DUT: Waiting for expected UI event") - assertThat(self._ui_event_stream).emits(get_passkey) - return passkey - - def input_pin(self, cert_address, pin): - """ - Respond to the UI event - """ - logging.info("DUT: Inputting pin code: %s" % str(pin)) - self.on_user_input( - cert_address=cert_address, reply_boolean=True, expected_ui_event=UiMsgType.DISPLAY_PIN_ENTRY, pin=pin) - - def on_user_input(self, cert_address, reply_boolean, expected_ui_event, pin=[]): - """ - Respond to the UI event - """ - if expected_ui_event is None: - return - - ui_id = -1 - - def get_unique_id(event): - if event.message_type == expected_ui_event: - nonlocal ui_id - ui_id = event.unique_id - return True - return False - - logging.info("DUT: Waiting for expected UI event") - assertThat(self._ui_event_stream).emits(get_unique_id) - callback_type = UiCallbackType.YES_NO if len(pin) == 0 else UiCallbackType.PIN - self.__send_ui_callback(cert_address, callback_type, reply_boolean, ui_id, pin) - - def get_address(self): - return self._device.address - - def wait_for_bond_event(self, expected_bond_event): - """ - A bond event will be triggered once the bond process - is complete. For the DUT we need to wait for it, - for Cert it isn't needed. - """ - logging.info("DUT: Waiting for Bond Event: %s " % expected_bond_event) - assertThat(self._bond_event_stream).emits( - lambda event: event.message_type == expected_bond_event or logging.info("DUT: Actual Bond Event: %s" % event.message_type) - ) - - def wait_for_enforce_security_event(self, expected_enforce_security_event): - """ - We expect a 'True' or 'False' from the enforce security call - - This interface will allow the caller to wait for a callback - result from enforcing security policy over the facade. - """ - logging.info("DUT: Waiting for enforce security event") - assertThat(self._enforce_security_policy_stream).emits( - lambda event: event.result == expected_enforce_security_event or logging.info(event.result)) - - def wait_for_disconnect_event(self): - """ - The Address is expected to be returned - """ - logging.info("DUT: Waiting for Disconnect Event") - assertThat(self._disconnect_event_stream).emits(lambda event: logging.info("event: %s" % event.address) or True) - - def enforce_security_policy(self, address, type, policy): - """ - Call to enforce classic security policy - """ - self._device.security.EnforceSecurityPolicy( - SecurityPolicyMessage( - address=common.BluetoothAddressWithType(address=common.BluetoothAddress(address=address), type=type), - policy=policy)) - - def get_oob_data_from_controller(self, oob_data_present): - self._device.security.GetOutOfBandData(empty_proto.Empty()) - oob_data = [] - - def get_oob_data(event): - nonlocal oob_data - oob_data = [ - list(event.p192_data.confirmation_value), - list(event.p192_data.random_value), [0 for i in range(0, 16)], [0 for i in range(0, 16)] - ] - return True - - assertThat(self._oob_data_event_stream).emits(get_oob_data) - return oob_data - - def close(self): - safeClose(self._ui_event_stream) - safeClose(self._bond_event_stream) - safeClose(self._enforce_security_policy_stream) - safeClose(self._disconnect_event_stream) - safeClose(self._oob_data_event_stream) -- GitLab From cb7a09033fbefab64d0b996406bf48f40d91fab6 Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Mon, 17 Jun 2024 17:46:44 -0700 Subject: [PATCH 0050/1446] Remove gd_sl4a tests The tests have not been run in over two years Bug: 333555245 Bug: 290640100 Test: None Flag: EXEMPT, dead code removal Change-Id: I7ee920d2ab8a1851024afbec21e63e542724a226 --- .../gatt/gatt_connect_low_layer_test.py | 547 ------------- .../tests/gd_sl4a/gd_sl4a_device_config.yaml | 35 - .../tests/gd_sl4a/gd_sl4a_test_runner.py | 64 -- .../gd_sl4a/hci/le_advanced_scanning_test.py | 720 ------------------ system/blueberry/tests/gd_sl4a/lib/ble_lib.py | 259 ------- .../tests/gd_sl4a/lib/bt_constants.py | 472 ------------ .../tests/gd_sl4a/lib/gd_sl4a_base_test.py | 148 ---- .../gd_sl4a/security/oob_pairing_sl4a_test.py | 292 ------- 8 files changed, 2537 deletions(-) delete mode 100644 system/blueberry/tests/gd_sl4a/gatt/gatt_connect_low_layer_test.py delete mode 100644 system/blueberry/tests/gd_sl4a/gd_sl4a_device_config.yaml delete mode 100644 system/blueberry/tests/gd_sl4a/gd_sl4a_test_runner.py delete mode 100644 system/blueberry/tests/gd_sl4a/hci/le_advanced_scanning_test.py delete mode 100644 system/blueberry/tests/gd_sl4a/lib/ble_lib.py delete mode 100644 system/blueberry/tests/gd_sl4a/lib/bt_constants.py delete mode 100644 system/blueberry/tests/gd_sl4a/lib/gd_sl4a_base_test.py delete mode 100644 system/blueberry/tests/gd_sl4a/security/oob_pairing_sl4a_test.py diff --git a/system/blueberry/tests/gd_sl4a/gatt/gatt_connect_low_layer_test.py b/system/blueberry/tests/gd_sl4a/gatt/gatt_connect_low_layer_test.py deleted file mode 100644 index 8b942930a1d..00000000000 --- a/system/blueberry/tests/gd_sl4a/gatt/gatt_connect_low_layer_test.py +++ /dev/null @@ -1,547 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2022 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import queue -import logging -import time -from datetime import timedelta -from grpc import RpcError - -import hci_packets as hci -from blueberry.facade.hci import le_advertising_manager_facade_pb2 as le_advertising_facade -from blueberry.facade.hci import le_initiator_address_facade_pb2 as le_initiator_address_facade -from blueberry.facade import common_pb2 as common -from blueberry.tests.gd.cert.closable import safeClose -from blueberry.tests.gd.cert.truth import assertThat -from blueberry.tests.gd.cert.py_le_acl_manager import PyLeAclManager -from blueberry.tests.gd_sl4a.lib import gd_sl4a_base_test -from blueberry.tests.gd_sl4a.lib.bt_constants import ble_scan_settings_modes, ble_address_types, scan_result, ble_scan_settings_phys, ble_scan_settings_callback_types -from blueberry.tests.gd_sl4a.lib.ble_lib import generate_ble_scan_objects -from blueberry.utils.bt_gatt_utils import setup_gatt_connection -from blueberry.utils.bt_gatt_utils import GattTestUtilsError -from blueberry.utils.bt_gatt_utils import disconnect_gatt_connection -from blueberry.utils.bt_gatt_utils import wait_for_gatt_disconnect_event -from blueberry.utils.bt_gatt_utils import wait_for_gatt_connection -from blueberry.utils.bt_gatt_utils import close_gatt_client -from mobly.controllers.android_device import AndroidDevice -from mobly import asserts -from mobly import test_runner -from mobly.signals import TestFailure - - -class GattConnectLowLayerTest(gd_sl4a_base_test.GdSl4aBaseTestClass): - - def setup_class(self): - super().setup_class(cert_module='HCI_INTERFACES') - self.bluetooth_gatt_list = [] - self.default_timeout = 30 # seconds - - def setup_test(self): - super().setup_test() - self.cert_le_acl_manager = PyLeAclManager(self.cert) - - def teardown_test(self): - try: - for bluetooth_gatt in self.bluetooth_gatt_list: - self.dut.sl4a.gattClientClose(bluetooth_gatt) - except Exception as err: - logging.error("Failed to close GATT client, error: {}".format(err)) - try: - safeClose(self.cert_le_acl_manager) - except RpcError as err: - logging.error("Failed to close CERT acl manager, error: {}".format(err)) - self.cert_le_acl_manager = None - super().teardown_test() - - def _set_cert_privacy_policy_with_random_address(self, random_address): - private_policy = le_initiator_address_facade.PrivacyPolicy( - address_policy=le_initiator_address_facade.AddressPolicy.USE_STATIC_ADDRESS, - address_with_type=common.BluetoothAddressWithType( - address=common.BluetoothAddress(address=bytes(random_address, encoding='utf8')), - type=common.RANDOM_DEVICE_ADDRESS)) - self.cert.hci_le_initiator_address.SetPrivacyPolicyForInitiatorAddress(private_policy) - - def _start_cert_advertising_with_random_address(self, device_name, random_address): - gap_name = hci.GapData(data_type=hci.GapDataType.COMPLETE_LOCAL_NAME, - data=list(bytes(device_name, encoding='utf8'))) - gap_data = le_advertising_facade.GapDataMsg(data=gap_name.serialize()) - config = le_advertising_facade.AdvertisingConfig( - advertisement=[gap_data], - interval_min=512, - interval_max=768, - advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND, - own_address_type=common.USE_RANDOM_DEVICE_ADDRESS, - channel_map=7, - filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES) - request = le_advertising_facade.CreateAdvertiserRequest(config=config) - logging.info("Creating advertiser") - create_response = self.cert.hci_le_advertising_manager.CreateAdvertiser(request) - logging.info("Created advertiser") - return create_response - - def _start_dut_scanning_for_address(self, address_type, address): - logging.info("Start scanning for address {} with address type {}".format(address, address_type)) - self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency']) - filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a) - # Start scanning on SL4A DUT side - self.dut.sl4a.bleSetScanFilterDeviceAddressAndType(address, int(address_type)) - self.dut.sl4a.bleBuildScanFilter(filter_list) - self.dut.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback) - return scan_callback - - def _wait_for_scan_result_event(self, expected_event_name): - try: - # Verify if there is scan result - event_info = self.dut.ed.pop_event(expected_event_name, self.default_timeout) - # Print out scan result - mac_address = event_info['data']['Result']['deviceInfo']['address'] - logging.info("Filter advertisement with address {}".format(mac_address)) - return mac_address, event_info - except queue.Empty as error: - logging.error("Could not find initial advertisement.") - return None, None - - def _stop_advertising(self, advertiser_id): - logging.info("Stop advertising") - remove_request = le_advertising_facade.RemoveAdvertiserRequest(advertiser_id=advertiser_id) - self.cert.hci_le_advertising_manager.RemoveAdvertiser(remove_request) - logging.info("Stopped advertising") - - def _stop_scanning(self, scan_callback): - logging.info("Stop scanning") - self.dut.sl4a.bleStopBleScan(scan_callback) - logging.info("Stopped scanning") - - def _disconnect_gatt(self, device: AndroidDevice, bluetooth_gatt, gatt_callback): - try: - disconnect_gatt_connection(device, bluetooth_gatt, gatt_callback) - except GattTestUtilsError as err: - logging.error(err) - asserts.fail("Cannot disconnect GATT , error={}".format(err)) - finally: - close_gatt_client(device, bluetooth_gatt) - if bluetooth_gatt in self.bluetooth_gatt_list: - self.bluetooth_gatt_list.remove(bluetooth_gatt) - - def _wait_for_gatt_connection(self, device: AndroidDevice, gatt_callback, bluetooth_gatt): - try: - wait_for_gatt_connection(device, gatt_callback, bluetooth_gatt, timeout=self.default_timeout) - except GattTestUtilsError as err: - logging.error(err) - asserts.fail("Cannot observe GATT connection , error={}".format(err)) - - def _wait_for_gatt_disconnection(self, device: AndroidDevice, gatt_callback): - try: - wait_for_gatt_disconnect_event(device, gatt_callback) - except GattTestUtilsError as err: - logging.error(err) - asserts.fail("Cannot observe GATT disconnection, error={}".format(err)) - - def test_autoconnect_gatt_without_pairing_and_disconnect_quickly(self): - """ - Steps: - 1. CERT: advertises with Random Static address - 2. DUT: connect without pairing within 30 seconds - 3. CERT: verify GATT connection - 4. Wait 5 seconds - 5. DUT: Disconnect GATT - 6. CERT: Verify that GATT is disconnected within 5 seconds - """ - # Use random address on cert side - logging.info("Setting random address") - RANDOM_ADDRESS = 'D0:05:04:03:02:01' - DEVICE_NAME = 'Im_The_CERT!' - self._set_cert_privacy_policy_with_random_address(RANDOM_ADDRESS) - logging.info("Set random address") - - self.cert_le_acl_manager.listen_for_incoming_connections() - - # Setup cert side to advertise - create_response = self._start_cert_advertising_with_random_address(DEVICE_NAME, RANDOM_ADDRESS) - logging.info("Started advertising") - - # Setup SL4A DUT side to scan - addr_type = ble_address_types["random"] - scan_callback_token = self._start_dut_scanning_for_address(addr_type, RANDOM_ADDRESS) - logging.info("Started scanning") - - # Wait for results - expected_event_name = scan_result.format(scan_callback_token) - scanned_mac_address, event_info = self._wait_for_scan_result_event(expected_event_name) - - self._stop_scanning(scan_callback_token) - assertThat(scanned_mac_address).isNotNone() - assertThat(scanned_mac_address).isEqualTo(RANDOM_ADDRESS) - - autoconnect = True - try: - bluetooth_gatt, gatt_callback = setup_gatt_connection(self.dut, - RANDOM_ADDRESS, - autoconnect, - timeout_seconds=self.default_timeout) - except GattTestUtilsError as err: - logging.error(err) - asserts.fail("Cannot make the first connection , error={}".format(err)) - return - cert_acl_connection = self.cert_le_acl_manager.complete_incoming_connection() - self.dut.log.info("Device {} connected first time".format(RANDOM_ADDRESS)) - self.dut.log.info("Sleeping 5 seconds to simulate real life connection") - time.sleep(5) - self.dut.log.info("Disconnecting GATT") - self._disconnect_gatt(self.dut, bluetooth_gatt, gatt_callback) - self.dut.log.info("Device {} disconnected first time from DUT".format(RANDOM_ADDRESS)) - logging.info("Waiting 5 seconds to disconnect from CERT") - cert_acl_connection.wait_for_disconnection_complete(timeout=timedelta(seconds=5)) - cert_acl_connection.close() - self._stop_advertising(create_response.advertiser_id) - - def test_autoconnect_gatt_twice_with_random_address_without_pairing(self): - """ - Steps: - 1. CERT: advertises with Random Static address - 2. DUT: connect without pairing - 3. CERT: verify GATT connection - 4. Wait 5 seconds - 5. DUT: Disconnect GATT - 6. CERT: Verify that GATT is disconnected within 30 seconds - 7. DUT: Try to connect to Cert again, and verify it can be connected - within 30 seconds - """ - # Use random address on cert side - logging.info("Setting random address") - RANDOM_ADDRESS = 'D0:05:04:03:02:01' - DEVICE_NAME = 'Im_The_CERT!' - self._set_cert_privacy_policy_with_random_address(RANDOM_ADDRESS) - logging.info("Set random address") - - self.cert_le_acl_manager.listen_for_incoming_connections() - - # Setup cert side to advertise - create_response = self._start_cert_advertising_with_random_address(DEVICE_NAME, RANDOM_ADDRESS) - logging.info("Started advertising") - - # Setup SL4A DUT side to scan - addr_type = ble_address_types["random"] - scan_callback_token = self._start_dut_scanning_for_address(addr_type, RANDOM_ADDRESS) - logging.info("Started scanning") - - # Wait for results - expected_event_name = scan_result.format(scan_callback_token) - scanned_mac_address, event_info = self._wait_for_scan_result_event(expected_event_name) - - self._stop_scanning(scan_callback_token) - assertThat(scanned_mac_address).isNotNone() - assertThat(scanned_mac_address).isEqualTo(RANDOM_ADDRESS) - - logging.info("Setting up first GATT connection to CERT") - autoconnect = True - try: - bluetooth_gatt, gatt_callback = setup_gatt_connection(self.dut, - RANDOM_ADDRESS, - autoconnect, - timeout_seconds=self.default_timeout) - except GattTestUtilsError as err: - logging.error(err) - asserts.fail("Cannot make the first connection , error={}".format(err)) - return - cert_acl_connection = self.cert_le_acl_manager.complete_incoming_connection() - # listen early as GATT might be reconnected on error - self.cert_le_acl_manager.listen_for_incoming_connections() - self.dut.log.info("Device {} connected first time".format(RANDOM_ADDRESS)) - self.dut.log.info("Sleeping 5 seconds to simulate real life connection") - time.sleep(5) - self.dut.log.info("Disconnecting first GATT connection") - self._disconnect_gatt(self.dut, bluetooth_gatt, gatt_callback) - self.dut.log.info("Device {} disconnected first time from DUT".format(RANDOM_ADDRESS)) - logging.info("Waiting 30 seconds to disconnect from CERT") - cert_acl_connection.wait_for_disconnection_complete(timeout=timedelta(seconds=30)) - logging.info("Setting up second GATT connection to CERT") - try: - bluetooth_gatt, gatt_callback = setup_gatt_connection(self.dut, - RANDOM_ADDRESS, - autoconnect, - timeout_seconds=self.default_timeout) - except GattTestUtilsError as err: - close_gatt_client(self.dut, bluetooth_gatt) - logging.error(err) - asserts.fail("Cannot make the second connection , error={}".format(err)) - cert_acl_connection = self.cert_le_acl_manager.complete_incoming_connection() - self.dut.log.info("Device {} connected second time".format(RANDOM_ADDRESS)) - self.dut.log.info("Disconnect second GATT connection") - self._disconnect_gatt(self.dut, bluetooth_gatt, gatt_callback) - logging.info("Wait for CERT to disconnect") - cert_acl_connection.wait_for_disconnection_complete(timeout=timedelta(seconds=30)) - cert_acl_connection.close() - self.dut.log.info("Device {} disconnected second time".format(RANDOM_ADDRESS)) - self._stop_advertising(create_response.advertiser_id) - - def test_disconnect_autoconnect_without_close(self): - """ - Steps: - 1. CERT: advertises with Random Static address - 2. DUT: connect without pairing within 30 seconds - 3. CERT: verify GATT connection - 4. Wait 5 seconds - 5. DUT: Disconnect GATT, but do not close it, keep CERT advertising ON - 6. CERT: Verify that GATT is disconnected within 5 seconds - 7. CERT: Verify that no further GATT connection is made - 8. CERT: Stop advertising - """ - # Use random address on cert side - logging.info("Setting random address") - RANDOM_ADDRESS = 'D0:05:04:03:02:01' - DEVICE_NAME = 'Im_The_CERT!' - self._set_cert_privacy_policy_with_random_address(RANDOM_ADDRESS) - logging.info("Set random address") - - self.cert_le_acl_manager.listen_for_incoming_connections() - - # Setup cert side to advertise - create_response = self._start_cert_advertising_with_random_address(DEVICE_NAME, RANDOM_ADDRESS) - logging.info("Started advertising") - - # Setup SL4A DUT side to scan - addr_type = ble_address_types["random"] - scan_callback_token = self._start_dut_scanning_for_address(addr_type, RANDOM_ADDRESS) - logging.info("Started scanning") - - # Wait for results - expected_event_name = scan_result.format(scan_callback_token) - scanned_mac_address, event_info = self._wait_for_scan_result_event(expected_event_name) - - self._stop_scanning(scan_callback_token) - assertThat(scanned_mac_address).isNotNone() - assertThat(scanned_mac_address).isEqualTo(RANDOM_ADDRESS) - - autoconnect = True - try: - bluetooth_gatt, gatt_callback = setup_gatt_connection(self.dut, - RANDOM_ADDRESS, - autoconnect, - timeout_seconds=self.default_timeout) - except GattTestUtilsError as err: - logging.error(err) - asserts.fail("Cannot make the first connection , error={}".format(err)) - return - cert_acl_connection = self.cert_le_acl_manager.complete_incoming_connection() - self.cert_le_acl_manager.listen_for_incoming_connections() - self.dut.log.info("Device {} connected first time".format(RANDOM_ADDRESS)) - self.dut.log.info("Sleeping 5 seconds to simulate real life connection") - time.sleep(5) - self.dut.log.info("Disconnect first GATT connection") - self._disconnect_gatt(self.dut, bluetooth_gatt, gatt_callback) - self.dut.log.info("Device {} disconnected first time from DUT".format(RANDOM_ADDRESS)) - logging.info("Waiting 5 seconds to disconnect from CERT") - cert_acl_connection.wait_for_disconnection_complete(timeout=timedelta(seconds=5)) - cert_acl_connection.close() - logging.info("Verifying that no further GATT connection is made") - try: - cert_acl_connection = self.cert_le_acl_manager.complete_incoming_connection() - asserts.fail("Should not have a GATT connection") - except TestFailure: - pass - logging.info("Stop advertising") - self._stop_advertising(create_response.advertiser_id) - - def test_autoconnect_without_proactive_disconnect(self): - """ - Steps: - 1. CERT: advertises with Random Static address - 2. DUT: connect without pairing within 30 seconds - 3. CERT: verify GATT connection - 4. Wait 5 seconds - 5. CERT: Turn off advertising - 6. CERT: Disconnect existing GATT connection - 7. DUT: Verify that GATT is disconnected within 5 seconds - 8. CERT: Start advertising - 9. DUT: Verify GATT connects within 5 seconds - 10. CERT: Stop advertising and disconnect DUT - 11. DUT: Verify that GATT disconnects within 5 seconds - """ - # Use random address on cert side - logging.info("Setting random address") - RANDOM_ADDRESS = 'D0:05:04:03:02:01' - DEVICE_NAME = 'Im_The_CERT!' - self._set_cert_privacy_policy_with_random_address(RANDOM_ADDRESS) - logging.info("Set random address") - - self.cert_le_acl_manager.listen_for_incoming_connections() - - # Setup cert side to advertise - create_response = self._start_cert_advertising_with_random_address(DEVICE_NAME, RANDOM_ADDRESS) - logging.info("Started advertising") - - # Setup SL4A DUT side to scan - addr_type = ble_address_types["random"] - scan_callback_token = self._start_dut_scanning_for_address(addr_type, RANDOM_ADDRESS) - logging.info("Started scanning") - - # Wait for results - expected_event_name = scan_result.format(scan_callback_token) - scanned_mac_address, event_info = self._wait_for_scan_result_event(expected_event_name) - - self._stop_scanning(scan_callback_token) - assertThat(scanned_mac_address).isNotNone() - assertThat(scanned_mac_address).isEqualTo(RANDOM_ADDRESS) - - autoconnect = True - try: - bluetooth_gatt, gatt_callback = setup_gatt_connection(self.dut, - RANDOM_ADDRESS, - autoconnect, - timeout_seconds=self.default_timeout) - except GattTestUtilsError as err: - logging.error(err) - asserts.fail("Cannot make the first connection , error={}".format(err)) - return - cert_acl_connection = self.cert_le_acl_manager.complete_incoming_connection() - self.dut.log.info("Device {} connected first time".format(RANDOM_ADDRESS)) - self.dut.log.info("Sleeping 5 seconds to simulate real life connection") - time.sleep(5) - logging.info("Stopping cert advertising") - self._stop_advertising(create_response.advertiser_id) - logging.info("Disconnecting cert") - cert_acl_connection.disconnect() - logging.info("Waiting for cert to disconnect") - cert_acl_connection.wait_for_disconnection_complete(timeout=timedelta(seconds=10)) - cert_acl_connection.close() - logging.info("Waiting for DUT to see disconnection") - self._wait_for_gatt_disconnection(self.dut, gatt_callback) - self.dut.log.info("Device {} disconnected first time from DUT".format(RANDOM_ADDRESS)) - logging.info("Waiting 5 seconds to disconnect from CERT") - logging.info("Start CERT advertising") - self.cert_le_acl_manager.listen_for_incoming_connections() - create_response = self._start_cert_advertising_with_random_address(DEVICE_NAME, RANDOM_ADDRESS) - logging.info("Waiting for GATT to connect") - self._wait_for_gatt_connection(self.dut, gatt_callback, bluetooth_gatt) - logging.info("Waiting on CERT as well for background connection") - cert_acl_connection = self.cert_le_acl_manager.complete_incoming_connection() - logging.info("GATT is connected via background connection") - self.dut.log.info("Sleeping 5 seconds to simulate real life connection") - time.sleep(5) - logging.info("Stopping cert advertising") - self._stop_advertising(create_response.advertiser_id) - logging.info("Disconnecting cert") - cert_acl_connection.disconnect() - logging.info("Waiting for cert to disconnect") - cert_acl_connection.wait_for_disconnection_complete(timeout=timedelta(seconds=10)) - cert_acl_connection.close() - logging.info("Waiting for DUT to see disconnection") - self._wait_for_gatt_disconnection(self.dut, gatt_callback) - logging.info("Verifying that no further GATT connection is made") - try: - self.cert_le_acl_manager.complete_incoming_connection() - asserts.fail("Should not have a GATT connection") - except TestFailure: - pass - - def test_autoconnect_without_proactive_disconnect_repeatedly(self): - """ - Steps: - 1. CERT: advertises with Random Static address - 2. DUT: connect without pairing within 30 seconds - 3. CERT: verify GATT connection - 4. Wait 5 seconds - 5. CERT: Turn off advertising - 6. CERT: Disconnect existing GATT connection - 7. DUT: Verify that GATT is disconnected within 5 seconds - 8. CERT: Start advertising - 9. DUT: Verify GATT connects within 5 seconds - 10. CERT: Stop advertising and disconnect DUT - 11. DUT: Verify that GATT disconnects within 5 seconds - 12. Repeat step 8 to 11 for 20 times - """ - # Use random address on cert side - logging.info("Setting random address") - RANDOM_ADDRESS = 'D0:05:04:03:02:01' - DEVICE_NAME = 'Im_The_CERT!' - self._set_cert_privacy_policy_with_random_address(RANDOM_ADDRESS) - logging.info("Set random address") - - self.cert_le_acl_manager.listen_for_incoming_connections() - - # Setup cert side to advertise - create_response = self._start_cert_advertising_with_random_address(DEVICE_NAME, RANDOM_ADDRESS) - logging.info("Started advertising") - - # Setup SL4A DUT side to scan - addr_type = ble_address_types["random"] - scan_callback_token = self._start_dut_scanning_for_address(addr_type, RANDOM_ADDRESS) - logging.info("Started scanning") - - # Wait for results - expected_event_name = scan_result.format(scan_callback_token) - scanned_mac_address, event_info = self._wait_for_scan_result_event(expected_event_name) - - self._stop_scanning(scan_callback_token) - assertThat(scanned_mac_address).isNotNone() - assertThat(scanned_mac_address).isEqualTo(RANDOM_ADDRESS) - - autoconnect = True - try: - bluetooth_gatt, gatt_callback = setup_gatt_connection(self.dut, - RANDOM_ADDRESS, - autoconnect, - timeout_seconds=self.default_timeout) - except GattTestUtilsError as err: - logging.error(err) - asserts.fail("Cannot make the first connection , error={}".format(err)) - return - cert_acl_connection = self.cert_le_acl_manager.complete_incoming_connection() - self.dut.log.info("Device {} connected first time".format(RANDOM_ADDRESS)) - self.dut.log.info("Sleeping 5 seconds to simulate real life connection") - time.sleep(5) - logging.info("Stopping CERT advertising") - self._stop_advertising(create_response.advertiser_id) - logging.info("Stopped CERT advertising, now disconnect cert") - cert_acl_connection.disconnect() - logging.info("Waiting for cert to disconnect") - cert_acl_connection.wait_for_disconnection_complete(timeout=timedelta(seconds=10)) - cert_acl_connection.close() - logging.info("Cert disconnected, waiting for DUT to see disconnection event") - self._wait_for_gatt_disconnection(self.dut, gatt_callback) - self.dut.log.info("Device {} disconnected first time from DUT".format(RANDOM_ADDRESS)) - logging.info("Waiting 5 seconds to disconnect from CERT") - for i in range(20): - logging.info("Start advertising on CERT") - self.cert_le_acl_manager.listen_for_incoming_connections() - create_response = self._start_cert_advertising_with_random_address(DEVICE_NAME, RANDOM_ADDRESS) - self.dut.log.info("Wait on DUT for background GATT connection") - self._wait_for_gatt_connection(self.dut, gatt_callback, bluetooth_gatt) - logging.info("Waiting on CERT as well for background connection") - cert_acl_connection = self.cert_le_acl_manager.complete_incoming_connection() - logging.info("GATT is connected via background connection") - self.dut.log.info("Sleeping 5 seconds to simulate real life connection") - time.sleep(5) - logging.info("Stop advertising from CERT") - self._stop_advertising(create_response.advertiser_id) - logging.info("Disconnect from CERT") - cert_acl_connection.disconnect() - logging.info("Waiting on CERT end for disconnection to happen") - cert_acl_connection.wait_for_disconnection_complete(timeout=timedelta(seconds=10)) - cert_acl_connection.close() - self.dut.log.info("Waiting on DUT end for disconnection to happen") - self._wait_for_gatt_disconnection(self.dut, gatt_callback) - logging.info("Verifying that no further GATT connection is made") - try: - cert_acl_connection = self.cert_le_acl_manager.complete_incoming_connection() - asserts.fail("Should not have a GATT connection") - except TestFailure: - pass - - -if __name__ == '__main__': - test_runner.main() diff --git a/system/blueberry/tests/gd_sl4a/gd_sl4a_device_config.yaml b/system/blueberry/tests/gd_sl4a/gd_sl4a_device_config.yaml deleted file mode 100644 index 19829b8f72e..00000000000 --- a/system/blueberry/tests/gd_sl4a/gd_sl4a_device_config.yaml +++ /dev/null @@ -1,35 +0,0 @@ -_description: Bluetooth cert testing with SL4A -TestBeds: - - Name: AndroidDeviceCert - Controllers: - GdDevice: - - grpc_port: '8898' - grpc_root_server_port: '8896' - signal_port: '8894' - label: cert - serial_number: 'CERT' - name: Cert Device - cmd: - - "adb" - - "-s" - - "$(serial_number)" - - "shell" - - "ASAN_OPTIONS=detect_container_overflow=0" - - "/system/bin/bluetooth_stack_with_facade" - - "--grpc-port=$(grpc_port)" - - "--root-server-port=$(grpc_root_server_port)" - - "--btsnoop=/data/misc/bluetooth/logs/btsnoop_hci.log" - - "--btsnooz=/data/misc/bluetooth/logs/btsnooz_hci.log" - - "--btconfig=/data/misc/bluedroid/bt_config.conf" - - "--signal-port=$(signal_port)" - AndroidDevice: - - label: dut - # Preferred client port number on the PC host side for SL4A - client_port: '8895' - # Preferred server port number forwarded from Android to the host PC - # via adb for SL4A connections - forwarded_port: '8899' - # Preferred server port used by SL4A on Android device - server_port: '8899' - serial: 'DUT' -logpath: "/tmp/logs" \ No newline at end of file diff --git a/system/blueberry/tests/gd_sl4a/gd_sl4a_test_runner.py b/system/blueberry/tests/gd_sl4a/gd_sl4a_test_runner.py deleted file mode 100644 index 803678af185..00000000000 --- a/system/blueberry/tests/gd_sl4a/gd_sl4a_test_runner.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2021 - 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. - -from blueberry.tests.gd_sl4a.hci.le_advanced_scanning_test import LeAdvancedScanningTest -from blueberry.tests.gd_sl4a.security.oob_pairing_sl4a_test import OobPairingSl4aTest -from blueberry.tests.gd_sl4a.gatt.gatt_connect_low_layer_test import GattConnectLowLayerTest - -from mobly import suite_runner -import argparse - -ALL_TESTS = [LeAdvancedScanningTest, OobPairingSl4aTest, GattConnectLowLayerTest] - - -def main(): - """ - Local test runner that allows to specify list of tests to and customize - test config file location - """ - parser = argparse.ArgumentParser(description="Run local GD SL4A tests.") - parser.add_argument( - '-c', '--config', type=str, required=True, metavar='', help='Path to the test configuration file.') - parser.add_argument( - '--tests', - '--test_case', - nargs='+', - type=str, - metavar='[ClassA[.test_a] ClassB[.test_b] ...]', - help='A list of test classes and optional tests to execute.') - parser.add_argument("--all_tests", "-A", type=bool, dest="all_tests", default=False, nargs="?") - parser.add_argument("--presubmit", type=bool, dest="presubmit", default=False, nargs="?") - parser.add_argument("--postsubmit", type=bool, dest="postsubmit", default=False, nargs="?") - args = parser.parse_args() - test_list = ALL_TESTS - if args.all_tests: - test_list = ALL_TESTS - elif args.presubmit: - test_list = ALL_TESTS - elif args.postsubmit: - test_list = ALL_TESTS - # Do not pass this layer's cmd line argument to next layer - argv = ["--config", args.config] - if args.tests: - argv.append("--tests") - for test in args.tests: - argv.append(test) - - suite_runner.run_suite(test_list, argv=argv) - - -if __name__ == "__main__": - main() diff --git a/system/blueberry/tests/gd_sl4a/hci/le_advanced_scanning_test.py b/system/blueberry/tests/gd_sl4a/hci/le_advanced_scanning_test.py deleted file mode 100644 index 981056c3852..00000000000 --- a/system/blueberry/tests/gd_sl4a/hci/le_advanced_scanning_test.py +++ /dev/null @@ -1,720 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2021 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import queue -import logging - -from google.protobuf import empty_pb2 as empty_proto - -import hci_packets as hci -from blueberry.facade.hci import le_advertising_manager_facade_pb2 as le_advertising_facade -from blueberry.facade.hci import le_initiator_address_facade_pb2 as le_initiator_address_facade -from blueberry.facade import common_pb2 as common -from blueberry.tests.gd.cert.truth import assertThat -from blueberry.tests.gd_sl4a.lib import gd_sl4a_base_test -from blueberry.tests.gd_sl4a.lib.bt_constants import ble_scan_settings_modes, ble_address_types, scan_result, ble_scan_settings_phys, ble_scan_settings_callback_types -from blueberry.tests.gd_sl4a.lib.ble_lib import generate_ble_scan_objects - -from mobly import test_runner - - -class LeAdvancedScanningTest(gd_sl4a_base_test.GdSl4aBaseTestClass): - - def setup_class(self): - super().setup_class(cert_module='HCI_INTERFACES') - self.default_timeout = 60 # seconds - - def setup_test(self): - super().setup_test() - - def teardown_test(self): - super().teardown_test() - - def __get_test_irk(self): - return bytes( - bytearray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10])) - - def _set_cert_privacy_policy_with_random_address(self, random_address): - private_policy = le_initiator_address_facade.PrivacyPolicy( - address_policy=le_initiator_address_facade.AddressPolicy.USE_STATIC_ADDRESS, - address_with_type=common.BluetoothAddressWithType( - address=common.BluetoothAddress(address=bytes(random_address, encoding='utf8')), - type=common.RANDOM_DEVICE_ADDRESS)) - self.cert.hci_le_initiator_address.SetPrivacyPolicyForInitiatorAddress(private_policy) - - def _set_cert_privacy_policy_with_random_address_but_advertise_resolvable(self, irk): - random_address_bytes = "DD:34:02:05:5C:EE".encode() - private_policy = le_initiator_address_facade.PrivacyPolicy( - address_policy=le_initiator_address_facade.AddressPolicy.USE_RESOLVABLE_ADDRESS, - address_with_type=common.BluetoothAddressWithType( - address=common.BluetoothAddress(address=random_address_bytes), type=common.RANDOM_DEVICE_ADDRESS), - rotation_irk=irk) - self.cert.hci_le_initiator_address.SetPrivacyPolicyForInitiatorAddress(private_policy) - # Bluetooth MAC address must be upper case - return random_address_bytes.decode('utf-8').upper() - - def __advertise_rpa_random_policy(self, legacy_pdus, irk): - DEVICE_NAME = 'Im_The_CERT!' - logging.info("Getting public address") - ADDRESS = self._set_cert_privacy_policy_with_random_address_but_advertise_resolvable(irk) - logging.info("Done %s" % ADDRESS) - - # Setup cert side to advertise - gap_name = hci.GapData(data_type=hci.GapDataType.COMPLETE_LOCAL_NAME, - data=list(bytes(DEVICE_NAME, encoding='utf8'))) - gap_data = le_advertising_facade.GapDataMsg(data=gap_name.serialize()) - config = le_advertising_facade.AdvertisingConfig( - advertisement=[gap_data], - interval_min=512, - interval_max=768, - advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND, - own_address_type=common.USE_RANDOM_DEVICE_ADDRESS, - channel_map=7, - filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES) - extended_config = le_advertising_facade.ExtendedAdvertisingConfig( - include_tx_power=True, - connectable=True, - legacy_pdus=legacy_pdus, - advertising_config=config, - secondary_advertising_phy=ble_scan_settings_phys["1m"]) - request = le_advertising_facade.ExtendedCreateAdvertiserRequest(config=extended_config) - logging.info("Creating %s PDU advertiser..." % ("Legacy" if legacy_pdus else "Extended")) - create_response = self.cert.hci_le_advertising_manager.ExtendedCreateAdvertiser(request) - logging.info("%s PDU advertiser created." % ("Legacy" if legacy_pdus else "Extended")) - return (ADDRESS, create_response) - - def _advertise_rpa_random_legacy_pdu(self, irk): - return self.__advertise_rpa_random_policy(True, irk) - - def _advertise_rpa_random_extended_pdu(self, irk): - return self.__advertise_rpa_random_policy(False, irk) - - def _set_cert_privacy_policy_with_public_address(self): - public_address_bytes = self.cert.hci_controller.GetMacAddress(empty_proto.Empty()).address - private_policy = le_initiator_address_facade.PrivacyPolicy( - address_policy=le_initiator_address_facade.AddressPolicy.USE_PUBLIC_ADDRESS, - address_with_type=common.BluetoothAddressWithType( - address=common.BluetoothAddress(address=public_address_bytes), type=common.PUBLIC_DEVICE_ADDRESS)) - self.cert.hci_le_initiator_address.SetPrivacyPolicyForInitiatorAddress(private_policy) - # Bluetooth MAC address must be upper case - return public_address_bytes.decode('utf-8').upper() - - def _set_cert_privacy_policy_with_public_address_but_advertise_resolvable(self, irk): - public_address_bytes = self.cert.hci_controller.GetMacAddress(empty_proto.Empty()).address - private_policy = le_initiator_address_facade.PrivacyPolicy( - address_policy=le_initiator_address_facade.AddressPolicy.USE_RESOLVABLE_ADDRESS, - address_with_type=common.BluetoothAddressWithType( - address=common.BluetoothAddress(address=public_address_bytes), type=common.PUBLIC_DEVICE_ADDRESS), - rotation_irk=irk) - self.cert.hci_le_initiator_address.SetPrivacyPolicyForInitiatorAddress(private_policy) - # Bluetooth MAC address must be upper case - return public_address_bytes.decode('utf-8').upper() - - def __advertise_rpa_public_policy(self, legacy_pdus, irk): - DEVICE_NAME = 'Im_The_CERT!' - logging.info("Getting public address") - ADDRESS = self._set_cert_privacy_policy_with_public_address_but_advertise_resolvable(irk) - logging.info("Done %s" % ADDRESS) - - # Setup cert side to advertise - gap_name = hci.GapData(data_type=hci.GapDataType.COMPLETE_LOCAL_NAME, - data=list(bytes(DEVICE_NAME, encoding='utf8'))) - gap_data = le_advertising_facade.GapDataMsg(data=gap_name.serialize()) - config = le_advertising_facade.AdvertisingConfig( - advertisement=[gap_data], - interval_min=512, - interval_max=768, - advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND, - own_address_type=common.USE_RANDOM_DEVICE_ADDRESS, - channel_map=7, - filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES) - extended_config = le_advertising_facade.ExtendedAdvertisingConfig( - include_tx_power=True, - connectable=True, - legacy_pdus=legacy_pdus, - advertising_config=config, - secondary_advertising_phy=ble_scan_settings_phys["1m"]) - request = le_advertising_facade.ExtendedCreateAdvertiserRequest(config=extended_config) - logging.info("Creating %s PDU advertiser..." % ("Legacy" if legacy_pdus else "Extended")) - create_response = self.cert.hci_le_advertising_manager.ExtendedCreateAdvertiser(request) - logging.info("%s PDU advertiser created." % ("Legacy" if legacy_pdus else "Extended")) - return (ADDRESS, create_response) - - def _advertise_rpa_public_legacy_pdu(self, irk): - return self.__advertise_rpa_public_policy(True, irk) - - def _advertise_rpa_public_extended_pdu(self, irk): - return self.__advertise_rpa_public_policy(False, irk) - - def _wait_for_scan_result_event(self, expected_event_name): - try: - # Verify if there is scan result - event_info = self.dut.ed.pop_event(expected_event_name, self.default_timeout) - # Print out scan result - mac_address = event_info['data']['Result']['deviceInfo']['address'] - logging.info("Filter advertisement with address {}".format(mac_address)) - return True - except queue.Empty as error: - logging.error("Could not find initial advertisement.") - return False - - def _stop_advertising(self, advertiser_id): - logging.info("Stop advertising") - remove_request = le_advertising_facade.RemoveAdvertiserRequest(advertiser_id=advertiser_id) - self.cert.hci_le_advertising_manager.RemoveAdvertiser(remove_request) - logging.info("Stopped advertising") - - def _stop_scanning(self, scan_callback): - logging.info("Stop scanning") - self.dut.sl4a.bleStopBleScan(scan_callback) - logging.info("Stopped scanning") - - def test_scan_filter_device_public_address_with_irk_legacy_pdu(self): - """ - The cert side will advertise a RRPA generated from the test IRK using Legacy PDU - - DUT will scan for the device using the Identity Address + Address Type + IRK - - Results received via ScanCallback - """ - PUBLIC_ADDRESS, create_response = self._advertise_rpa_public_legacy_pdu(self.__get_test_irk()) - addr_type = ble_address_types["public"] - logging.info("Start scanning for PUBLIC_ADDRESS %s with address type %d and IRK %s" % - (PUBLIC_ADDRESS, addr_type, self.__get_test_irk().decode("utf-8"))) - - # Setup SL4A DUT side to scan - self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency']) - filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a) - expected_event_name = scan_result.format(scan_callback) - - # Start scanning on SL4A DUT side - self.dut.sl4a.bleSetScanFilterDeviceAddressTypeAndIrk(PUBLIC_ADDRESS, int(addr_type), - self.__get_test_irk().decode("utf-8")) - self.dut.sl4a.bleBuildScanFilter(filter_list) - self.dut.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback) - logging.info("Started scanning") - - # Wait for results - got_result = self._wait_for_scan_result_event(expected_event_name) - - # Test over - self._stop_scanning(scan_callback) - self._stop_advertising(create_response.advertiser_id) - - assertThat(got_result).isTrue() - - def test_scan_filter_device_public_address_with_irk_legacy_pdu_pending_intent(self): - """ - The cert side will advertise a RRPA generated from the test IRK using Legacy PDU - - DUT will scan for the device using the Identity Address + Address Type + IRK - - Results received via PendingIntent - """ - PUBLIC_ADDRESS, create_response = self._advertise_rpa_public_legacy_pdu(self.__get_test_irk()) - addr_type = ble_address_types["public"] - logging.info("Start scanning for PUBLIC_ADDRESS %s with address type %d and IRK %s" % - (PUBLIC_ADDRESS, addr_type, self.__get_test_irk().decode("utf-8"))) - - # Setup SL4A DUT side to scan - self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency']) - filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a) - # The event name needs to be set to this otherwise the index iterates from the scancallbacks - # being run consecutively. This is a PendingIntent callback but it hooks into the - # ScanCallback and uses just the 1 for the index. - expected_event_name = "BleScan1onScanResults" - - # Start scanning on SL4A DUT side - self.dut.sl4a.bleSetScanFilterDeviceAddressTypeAndIrk(PUBLIC_ADDRESS, int(addr_type), - self.__get_test_irk().decode("utf-8")) - self.dut.sl4a.bleBuildScanFilter(filter_list) - self.dut.sl4a.bleStartBleScanPendingIntent(filter_list, scan_settings) - logging.info("Started scanning") - - # Wait for results - got_result = self._wait_for_scan_result_event(expected_event_name) - - # Test over - self._stop_scanning(scan_callback) - self._stop_advertising(create_response.advertiser_id) - - assertThat(got_result).isTrue() - - def test_scan_filter_device_public_address_with_irk_extended_pdu(self): - """ - The cert side will advertise a RRPA generated from the test IRK using Extended PDU - - DUT will scan for the device using the Identity Address + Address Type + IRK - - Results received via PendingIntent - """ - PUBLIC_ADDRESS, create_response = self._advertise_rpa_public_extended_pdu(self.__get_test_irk()) - addr_type = ble_address_types["public"] - logging.info("Start scanning for PUBLIC_ADDRESS %s with address type %d and IRK %s" % - (PUBLIC_ADDRESS, addr_type, self.__get_test_irk().decode("utf-8"))) - - # Setup SL4A DUT side to scan - self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency']) - self.dut.sl4a.bleSetScanSettingsLegacy(False) - filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a) - expected_event_name = scan_result.format(scan_callback) - - # Start scanning on SL4A DUT side - self.dut.sl4a.bleSetScanFilterDeviceAddressTypeAndIrk(PUBLIC_ADDRESS, int(addr_type), - self.__get_test_irk().decode("utf-8")) - self.dut.sl4a.bleBuildScanFilter(filter_list) - self.dut.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback) - logging.info("Started scanning") - - # Wait for results - got_result = self._wait_for_scan_result_event(expected_event_name) - - # Test over - self._stop_scanning(scan_callback) - self._stop_advertising(create_response.advertiser_id) - - assertThat(got_result).isTrue() - - def test_scan_filter_device_name_legacy_pdu(self): - """ - The cert side will advertise using PUBLIC address and device name data on legacy PDU - - DUT will scan for the device using the Device Name - - Results received via ScanCallback - """ - # Use public address on cert side - logging.info("Setting public address") - DEVICE_NAME = 'Im_The_CERT!' - public_address = self._set_cert_privacy_policy_with_public_address() - logging.info("Set public address") - - # Setup cert side to advertise - gap_name = hci.GapData(data_type=hci.GapDataType.COMPLETE_LOCAL_NAME, - data=list(bytes(DEVICE_NAME, encoding='utf8'))) - gap_data = le_advertising_facade.GapDataMsg(data=gap_name.serialize()) - config = le_advertising_facade.AdvertisingConfig( - advertisement=[gap_data], - interval_min=512, - interval_max=768, - advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND, - own_address_type=common.USE_PUBLIC_DEVICE_ADDRESS, - channel_map=7, - filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES, - tx_power=20) - request = le_advertising_facade.CreateAdvertiserRequest(config=config) - logging.info("Creating advertiser") - create_response = self.cert.hci_le_advertising_manager.CreateAdvertiser(request) - logging.info("Created advertiser") - - # Setup SL4A DUT side to scan - logging.info("Start scanning with public address %s" % public_address) - self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency']) - filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a) - expected_event_name = scan_result.format(scan_callback) - - # Start scanning on SL4A DUT side - self.dut.sl4a.bleSetScanFilterDeviceName(DEVICE_NAME) - self.dut.sl4a.bleBuildScanFilter(filter_list) - self.dut.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback) - logging.info("Started scanning") - - # Wait for results - got_result = self._wait_for_scan_result_event(expected_event_name) - - # Test over - self._stop_scanning(scan_callback) - self._stop_advertising(create_response.advertiser_id) - - assertThat(got_result).isTrue() - - def test_scan_filter_device_random_address_legacy_pdu(self): - """ - The cert side will advertise using RANDOM STATIC address with legacy PDU - - DUT will scan for the device using the RANDOM STATIC Address of the advertising device - - Results received via ScanCallback - """ - # Use random address on cert side - logging.info("Setting random address") - RANDOM_ADDRESS = 'D0:05:04:03:02:01' - DEVICE_NAME = 'Im_The_CERT!' - self._set_cert_privacy_policy_with_random_address(RANDOM_ADDRESS) - logging.info("Set random address") - - # Setup cert side to advertise - gap_name = hci.GapData(data_type=hci.GapDataType.COMPLETE_LOCAL_NAME, - data=list(bytes(DEVICE_NAME, encoding='utf8'))) - gap_data = le_advertising_facade.GapDataMsg(data=gap_name.serialize()) - config = le_advertising_facade.AdvertisingConfig( - advertisement=[gap_data], - interval_min=512, - interval_max=768, - advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND, - own_address_type=common.USE_RANDOM_DEVICE_ADDRESS, - channel_map=7, - filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES) - request = le_advertising_facade.CreateAdvertiserRequest(config=config) - logging.info("Creating advertiser") - create_response = self.cert.hci_le_advertising_manager.CreateAdvertiser(request) - logging.info("Created advertiser") - - # Setup SL4A DUT side to scan - addr_type = ble_address_types["random"] - logging.info("Start scanning for RANDOM_ADDRESS %s with address type %d" % (RANDOM_ADDRESS, addr_type)) - self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency']) - filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a) - expected_event_name = scan_result.format(scan_callback) - - # Start scanning on SL4A DUT side - self.dut.sl4a.bleSetScanFilterDeviceAddressAndType(RANDOM_ADDRESS, int(addr_type)) - self.dut.sl4a.bleBuildScanFilter(filter_list) - self.dut.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback) - logging.info("Started scanning") - - # Wait for results - got_result = self._wait_for_scan_result_event(expected_event_name) - - # Test over - self._stop_scanning(scan_callback) - self._stop_advertising(create_response.advertiser_id) - - assertThat(got_result).isTrue() - - def test_scan_filter_device_public_address_extended_pdu(self): - """ - The cert side will advertise using PUBLIC address with Extended PDU - - DUT will scan for the device using the PUBLIC Address of the advertising device - - Results received via ScanCallback - """ - # Use public address on cert side - logging.info("Setting public address") - DEVICE_NAME = 'Im_The_CERT!' - public_address = self._set_cert_privacy_policy_with_public_address() - logging.info("Set public address") - - # Setup cert side to advertise - gap_name = hci.GapData(data_type=hci.GapDataType.COMPLETE_LOCAL_NAME, - data=list(bytes(DEVICE_NAME, encoding='utf8'))) - gap_data = le_advertising_facade.GapDataMsg(data=gap_name.serialize()) - config = le_advertising_facade.AdvertisingConfig( - advertisement=[gap_data], - interval_min=512, - interval_max=768, - advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND, - own_address_type=common.USE_PUBLIC_DEVICE_ADDRESS, - channel_map=7, - filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES) - extended_config = le_advertising_facade.ExtendedAdvertisingConfig( - advertising_config=config, secondary_advertising_phy=ble_scan_settings_phys["1m"]) - request = le_advertising_facade.ExtendedCreateAdvertiserRequest(config=extended_config) - logging.info("Creating advertiser") - create_response = self.cert.hci_le_advertising_manager.ExtendedCreateAdvertiser(request) - logging.info("Created advertiser") - - # Setup SL4A DUT side to scan - addr_type = ble_address_types["public"] - logging.info("Start scanning for PUBLIC_ADDRESS %s with address type %d" % (public_address, addr_type)) - self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency']) - self.dut.sl4a.bleSetScanSettingsLegacy(False) - filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a) - expected_event_name = scan_result.format(scan_callback) - - # Start scanning on SL4A DUT side - self.dut.sl4a.bleSetScanFilterDeviceAddressAndType(public_address, int(addr_type)) - self.dut.sl4a.bleBuildScanFilter(filter_list) - self.dut.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback) - logging.info("Started scanning") - - # Wait for results - got_result = self._wait_for_scan_result_event(expected_event_name) - - # Test over - self._stop_scanning(scan_callback) - self._stop_advertising(create_response.advertiser_id) - - assertThat(got_result).isTrue() - - def test_scan_filter_device_public_address_with_irk_extended_pdu_pending_intent(self): - """ - The cert side will advertise using RRPA with Extended PDU - - DUT will scan for the device using the pre-shared PUBLIC ADDRESS of the advertising - device + IRK - - Results received via PendingIntent - """ - PUBLIC_ADDRESS, create_response = self._advertise_rpa_public_extended_pdu(self.__get_test_irk()) - - # Setup SL4A DUT side to scan - addr_type = ble_address_types["public"] - logging.info("Start scanning for PUBLIC_ADDRESS %s with address type %d and IRK %s" % - (PUBLIC_ADDRESS, addr_type, self.__get_test_irk().decode("utf-8"))) - self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency']) - self.dut.sl4a.bleSetScanSettingsLegacy(False) - filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a) - # Hard code here since callback index iterates and will cause this to fail if ran - # Second as the impl in SL4A sends this since its a single callback for broadcast. - expected_event_name = "BleScan1onScanResults" - - # Start scanning on SL4A DUT side - self.dut.sl4a.bleSetScanFilterDeviceAddressTypeAndIrk(PUBLIC_ADDRESS, int(addr_type), - self.__get_test_irk().decode("utf-8")) - self.dut.sl4a.bleBuildScanFilter(filter_list) - self.dut.sl4a.bleStartBleScanPendingIntent(filter_list, scan_settings) - logging.info("Started scanning") - - # Wait for results - got_result = self._wait_for_scan_result_event(expected_event_name) - - # Test over - self._stop_scanning(scan_callback) - self._stop_advertising(create_response.advertiser_id) - - assertThat(got_result).isTrue() - - def test_scan_filter_device_random_address_with_irk_extended_pdu(self): - """ - The cert side will advertise using RRPA with Extended PDU - - DUT will scan for the device using the pre-shared RANDOM STATIC ADDRESS of the advertising - device + IRK - - Results received via ScanCallback - """ - RANDOM_ADDRESS, create_response = self._advertise_rpa_random_extended_pdu(self.__get_test_irk()) - - # Setup SL4A DUT side to scan - addr_type = ble_address_types["random"] - logging.info("Start scanning for RANDOM_ADDRESS %s with address type %d and IRK %s" % - (RANDOM_ADDRESS, addr_type, self.__get_test_irk().decode("utf-8"))) - self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency']) - self.dut.sl4a.bleSetScanSettingsLegacy(False) - filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a) - expected_event_name = scan_result.format(scan_callback) - - # Setup SL4A DUT filter - self.dut.sl4a.bleSetScanFilterDeviceAddressTypeAndIrk(RANDOM_ADDRESS, int(addr_type), - self.__get_test_irk().decode("utf-8")) - self.dut.sl4a.bleBuildScanFilter(filter_list) - - # Start scanning on SL4A DUT side - self.dut.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback) - logging.info("Started scanning") - - # Wait for results - got_result = self._wait_for_scan_result_event(expected_event_name) - - # Test over - self._stop_scanning(scan_callback) - self._stop_advertising(create_response.advertiser_id) - - assertThat(got_result).isTrue() - - def test_scan_filter_device_random_address_with_irk_extended_pdu_pending_intent(self): - """ - The cert side will advertise using RRPA with Extended PDU - - DUT will scan for the device using the pre-shared RANDOM STATIC ADDRESS of the advertising - device + IRK - - Results received via PendingIntent - """ - RANDOM_ADDRESS, create_response = self._advertise_rpa_random_extended_pdu(self.__get_test_irk()) - - # Setup SL4A DUT side to scan - addr_type = ble_address_types["random"] - logging.info("Start scanning for RANDOM_ADDRESS %s with address type %d and IRK %s" % - (RANDOM_ADDRESS, addr_type, self.__get_test_irk().decode("utf-8"))) - self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency']) - self.dut.sl4a.bleSetScanSettingsLegacy(False) - filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a) - # Hard code here since callback index iterates and will cause this to fail if ran - # Second as the impl in SL4A sends this since its a single callback for broadcast. - expected_event_name = "BleScan1onScanResults" - - # Setup SL4A DUT filter - self.dut.sl4a.bleSetScanFilterDeviceAddressTypeAndIrk(RANDOM_ADDRESS, int(addr_type), - self.__get_test_irk().decode("utf-8")) - self.dut.sl4a.bleBuildScanFilter(filter_list) - - # Start scanning on SL4A DUT side - self.dut.sl4a.bleStartBleScanPendingIntent(filter_list, scan_settings) - logging.info("Started scanning") - - # Wait for results - got_result = self._wait_for_scan_result_event(expected_event_name) - - # Test over - self._stop_scanning(scan_callback) - self._stop_advertising(create_response.advertiser_id) - - assertThat(got_result).isTrue() - - def test_scan_filter_device_random_address_with_irk_extended_pdu_scan_twice(self): - """ - The cert side will advertise using RRPA with Extended PDU - - DUT will scan for the device using the pre-shared RANDOM STATIC ADDRESS of the advertising - device + IRK - - DUT will stop scanning, then start scanning again for results - - Results received via ScanCallback - """ - RANDOM_ADDRESS, create_response = self._advertise_rpa_random_extended_pdu(self.__get_test_irk()) - - # Setup SL4A DUT side to scan - addr_type = ble_address_types["random"] - logging.info("Start scanning for RANDOM_ADDRESS %s with address type %d and IRK %s" % - (RANDOM_ADDRESS, addr_type, self.__get_test_irk().decode("utf-8"))) - self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency']) - self.dut.sl4a.bleSetScanSettingsLegacy(False) - filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a) - expected_event_name = scan_result.format(scan_callback) - - # Start scanning on SL4A DUT side - self.dut.sl4a.bleSetScanFilterDeviceAddressTypeAndIrk(RANDOM_ADDRESS, int(addr_type), - self.__get_test_irk().decode("utf-8")) - self.dut.sl4a.bleBuildScanFilter(filter_list) - self.dut.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback) - logging.info("Started scanning") - - # Wait for results - got_result = self._wait_for_scan_result_event(expected_event_name) - - # Test over - self._stop_scanning(scan_callback) - - # Start scanning on SL4A DUT side - self.dut.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback) - logging.info("Started scanning...again") - - # Wait for results - got_result = self._wait_for_scan_result_event(expected_event_name) - - # Test over - self._stop_scanning(scan_callback) - self._stop_advertising(create_response.advertiser_id) - - assertThat(got_result).isTrue() - - def test_scan_filter_device_random_address_with_irk_extended_pdu_pending_intent_128_640(self): - """ - The CERT side will advertise an RPA derived from the IRK. - - The DUT (SL4A) side will scan for a RPA with matching IRK. - - Adjust the scan intervals to Digital Carkey specific timings. - """ - DEVICE_NAME = 'Im_The_CERT!' - logging.info("Getting public address") - RANDOM_ADDRESS = self._set_cert_privacy_policy_with_random_address_but_advertise_resolvable( - self.__get_test_irk()) - logging.info("Done %s" % RANDOM_ADDRESS) - - legacy_pdus = False - - # Setup cert side to advertise - gap_name = hci.GapData(data_type=hci.GapDataType.COMPLETE_LOCAL_NAME, - data=list(bytes(DEVICE_NAME, encoding='utf8'))) - gap_data = le_advertising_facade.GapDataMsg(data=gap_name.serialize()) - config = le_advertising_facade.AdvertisingConfig( - advertisement=[gap_data], - interval_min=128, - interval_max=640, - advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND, - own_address_type=common.USE_RANDOM_DEVICE_ADDRESS, - channel_map=7, - filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES) - extended_config = le_advertising_facade.ExtendedAdvertisingConfig( - include_tx_power=True, - connectable=True, - legacy_pdus=legacy_pdus, - advertising_config=config, - secondary_advertising_phy=ble_scan_settings_phys["1m"]) - request = le_advertising_facade.ExtendedCreateAdvertiserRequest(config=extended_config) - logging.info("Creating %s PDU advertiser..." % ("Legacy" if legacy_pdus else "Extended")) - create_response = self.cert.hci_le_advertising_manager.ExtendedCreateAdvertiser(request) - logging.info("%s PDU advertiser created." % ("Legacy" if legacy_pdus else "Extended")) - - # Setup SL4A DUT side to scan - addr_type = ble_address_types["random"] - logging.info("Start scanning for RANDOM_ADDRESS %s with address type %d and IRK %s" % - (RANDOM_ADDRESS, addr_type, self.__get_test_irk().decode("utf-8"))) - self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['ambient_discovery']) - self.dut.sl4a.bleSetScanSettingsLegacy(False) - filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a) - # Hard code here since callback index iterates and will cause this to fail if ran - # Second as the impl in SL4A sends this since its a single callback for broadcast. - expected_event_name = "BleScan1onScanResults" - - # Start scanning on SL4A DUT side - self.dut.sl4a.bleSetScanFilterDeviceAddressTypeAndIrk(RANDOM_ADDRESS, int(addr_type), - self.__get_test_irk().decode("utf-8")) - self.dut.sl4a.bleBuildScanFilter(filter_list) - self.dut.sl4a.bleStartBleScanPendingIntent(filter_list, scan_settings) - logging.info("Started scanning") - - # Wait for results - got_result = self._wait_for_scan_result_event(expected_event_name) - - # Test over - self._stop_scanning(scan_callback) - self._stop_advertising(create_response.advertiser_id) - - assertThat(got_result).isTrue() - - def test_scan_filter_lost_random_address_with_irk(self): - RANDOM_ADDRESS, create_response = self._advertise_rpa_random_extended_pdu(self.__get_test_irk()) - - # Setup SL4A DUT side to scan - addr_type = ble_address_types["random"] - logging.info("Start scanning for RANDOM_ADDRESS %s with address type %d and IRK %s" % - (RANDOM_ADDRESS, addr_type, self.__get_test_irk().decode("utf-8"))) - self.dut.sl4a.bleSetScanSettingsScanMode(ble_scan_settings_modes['low_latency']) - self.dut.sl4a.bleSetScanSettingsLegacy(False) - self.dut.sl4a.bleSetScanSettingsCallbackType(ble_scan_settings_callback_types['found_and_lost']) - filter_list, scan_settings, scan_callback = generate_ble_scan_objects(self.dut.sl4a) - expected_event_name = scan_result.format(scan_callback) - - # Start scanning on SL4A DUT side - self.dut.sl4a.bleSetScanFilterDeviceAddressTypeAndIrk(RANDOM_ADDRESS, int(addr_type), - self.__get_test_irk().decode("utf-8")) - self.dut.sl4a.bleBuildScanFilter(filter_list) - self.dut.sl4a.bleStartBleScan(filter_list, scan_settings, scan_callback) - logging.info("Started scanning") - - # Wait for found event to ensure scanning is started before stopping the advertiser - # to trigger lost event, else the lost event might not be caught by the test - got_found_result = self._wait_for_scan_result_event(expected_event_name) - assertThat(got_found_result).isTrue() - - self._stop_advertising(create_response.advertiser_id) - - # Wait for lost event - got_lost_result = self._wait_for_scan_result_event(expected_event_name) - assertThat(got_lost_result).isTrue() - - # Test over - self._stop_scanning(scan_callback) - - -if __name__ == '__main__': - test_runner.main() diff --git a/system/blueberry/tests/gd_sl4a/lib/ble_lib.py b/system/blueberry/tests/gd_sl4a/lib/ble_lib.py deleted file mode 100644 index 93b3eaece2c..00000000000 --- a/system/blueberry/tests/gd_sl4a/lib/ble_lib.py +++ /dev/null @@ -1,259 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2016 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. -""" -Ble libraries -""" - -import time -import queue -import logging - -from blueberry.tests.gd_sl4a.lib.bt_constants import ble_advertise_settings_modes -from blueberry.tests.gd_sl4a.lib.bt_constants import small_timeout -from blueberry.tests.gd_sl4a.lib.bt_constants import adv_fail -from blueberry.tests.gd_sl4a.lib.bt_constants import adv_succ -from blueberry.tests.gd_sl4a.lib.bt_constants import advertising_set_on_own_address_read -from blueberry.tests.gd_sl4a.lib.bt_constants import advertising_set_started -from blueberry.tests.gd_sl4a.lib.bt_constants import bluetooth_on -from blueberry.tests.gd_sl4a.lib.bt_constants import bluetooth_off -from blueberry.tests.gd_sl4a.lib.bt_constants import bt_default_timeout - - -def enable_bluetooth(sl4a, ed): - if sl4a.bluetoothCheckState(): - return True - - sl4a.bluetoothToggleState(True) - expected_bluetooth_on_event_name = bluetooth_on - try: - ed.pop_event(expected_bluetooth_on_event_name, bt_default_timeout) - except Exception: - logging.info("Failed to toggle Bluetooth on (no broadcast received)") - if sl4a.bluetoothCheckState(): - logging.info(".. actual state is ON") - return True - logging.info(".. actual state is OFF") - return False - - return True - - -def disable_bluetooth(sl4a, ed): - if not sl4a.bluetoothCheckState(): - return True - sl4a.bluetoothToggleState(False) - expected_bluetooth_off_event_name = bluetooth_off - try: - ed.pop_event(expected_bluetooth_off_event_name, bt_default_timeout) - except Exception: - logging.info("Failed to toggle Bluetooth off (no broadcast received)") - if sl4a.bluetoothCheckState(): - logging.info(".. actual state is ON") - return False - logging.info(".. actual state is OFF") - return True - return True - - -def generate_ble_scan_objects(sl4a): - """Generate generic LE scan objects. - - Args: - sl4a: The SL4A object to generate LE scan objects from. - - Returns: - filter_list: The generated scan filter list id. - scan_settings: The generated scan settings id. - scan_callback: The generated scan callback id. - """ - filter_list = sl4a.bleGenFilterList() - scan_settings = sl4a.bleBuildScanSetting() - scan_callback = sl4a.bleGenScanCallback() - return filter_list, scan_settings, scan_callback - - -def generate_ble_advertise_objects(sl4a): - """Generate generic LE advertise objects. - - Args: - sl4a: The SL4A object to generate advertise LE objects from. - - Returns: - advertise_callback: The generated advertise callback id. - advertise_data: The generated advertise data id. - advertise_settings: The generated advertise settings id. - """ - advertise_callback = sl4a.bleGenBleAdvertiseCallback() - advertise_data = sl4a.bleBuildAdvertiseData() - advertise_settings = sl4a.bleBuildAdvertiseSettings() - return advertise_callback, advertise_data, advertise_settings - - -class BleLib(): - - def __init__(self, dut): - self.advertisement_list = [] - self.dut = dut - self.default_timeout = 5 - self.set_advertisement_list = [] - self.generic_uuid = "0000{}-0000-1000-8000-00805f9b34fb" - - def _verify_ble_adv_started(self, advertise_callback): - """Helper for verifying if an advertisment started or not""" - regex = "({}|{})".format(adv_succ.format(advertise_callback), adv_fail.format(advertise_callback)) - try: - event = self.dut.ed.pop_events(regex, 5, small_timeout) - except queue.Empty: - logging.error("Failed to get success or failed event.") - return - if event[0]["name"] == adv_succ.format(advertise_callback): - logging.info("Advertisement started successfully.") - return True - else: - logging.info("Advertisement failed to start.") - return False - - def start_generic_connectable_advertisement(self, line): - """Start a connectable LE advertisement""" - scan_response = None - if line: - scan_response = bool(line) - self.dut.sl4a.bleSetAdvertiseSettingsAdvertiseMode(ble_advertise_settings_modes['low_latency']) - self.dut.sl4a.bleSetAdvertiseSettingsIsConnectable(True) - advertise_callback, advertise_data, advertise_settings = (generate_ble_advertise_objects(self.dut.sl4a)) - if scan_response: - self.dut.sl4a.bleStartBleAdvertisingWithScanResponse(advertise_callback, advertise_data, advertise_settings, - advertise_data) - else: - self.dut.sl4a.bleStartBleAdvertising(advertise_callback, advertise_data, advertise_settings) - if self._verify_ble_adv_started(advertise_callback): - logging.info("Tracking Callback ID: {}".format(advertise_callback)) - self.advertisement_list.append(advertise_callback) - logging.info(self.advertisement_list) - - def start_connectable_advertisement_set(self, line): - """Start Connectable Advertisement Set""" - adv_callback = self.dut.sl4a.bleAdvSetGenCallback() - adv_data = { - "includeDeviceName": True, - } - self.dut.sl4a.bleAdvSetStartAdvertisingSet({ - "connectable": True, - "legacyMode": False, - "primaryPhy": "PHY_LE_1M", - "secondaryPhy": "PHY_LE_1M", - "interval": 320 - }, adv_data, None, None, None, 0, 0, adv_callback) - evt = self.dut.ed.pop_event(advertising_set_started.format(adv_callback), self.default_timeout) - set_id = evt['data']['setId'] - logging.error("did not receive the set started event!") - evt = self.dut.ed.pop_event(advertising_set_on_own_address_read.format(set_id), self.default_timeout) - address = evt['data']['address'] - logging.info("Advertiser address is: {}".format(str(address))) - self.set_advertisement_list.append(adv_callback) - - def stop_all_advertisement_set(self, line): - """Stop all Advertisement Sets""" - for adv in self.set_advertisement_list: - try: - self.dut.sl4a.bleAdvSetStopAdvertisingSet(adv) - except Exception as err: - logging.error("Failed to stop advertisement: {}".format(err)) - - def adv_add_service_uuid_list(self, line): - """Add service UUID to the LE advertisement inputs: - [uuid1 uuid2 ... uuidN]""" - uuids = line.split() - uuid_list = [] - for uuid in uuids: - if len(uuid) == 4: - uuid = self.generic_uuid.format(line) - uuid_list.append(uuid) - self.dut.sl4a.bleSetAdvertiseDataSetServiceUuids(uuid_list) - - def adv_data_include_local_name(self, is_included): - """Include local name in the advertisement. inputs: [true|false]""" - self.dut.sl4a.bleSetAdvertiseDataIncludeDeviceName(bool(is_included)) - - def adv_data_include_tx_power_level(self, is_included): - """Include tx power level in the advertisement. inputs: [true|false]""" - self.dut.sl4a.bleSetAdvertiseDataIncludeTxPowerLevel(bool(is_included)) - - def adv_data_add_manufacturer_data(self, line): - """Include manufacturer id and data to the advertisment: - [id data1 data2 ... dataN]""" - info = line.split() - manu_id = int(info[0]) - manu_data = [] - for data in info[1:]: - manu_data.append(int(data)) - self.dut.sl4a.bleAddAdvertiseDataManufacturerId(manu_id, manu_data) - - def start_generic_nonconnectable_advertisement(self, line): - """Start a nonconnectable LE advertisement""" - self.dut.sl4a.bleSetAdvertiseSettingsAdvertiseMode(ble_advertise_settings_modes['low_latency']) - self.dut.sl4a.bleSetAdvertiseSettingsIsConnectable(False) - advertise_callback, advertise_data, advertise_settings = (generate_ble_advertise_objects(self.dut.sl4a)) - self.dut.sl4a.bleStartBleAdvertising(advertise_callback, advertise_data, advertise_settings) - if self._verify_ble_adv_started(advertise_callback): - logging.info("Tracking Callback ID: {}".format(advertise_callback)) - self.advertisement_list.append(advertise_callback) - logging.info(self.advertisement_list) - - def stop_all_advertisements(self, line): - """Stop all LE advertisements""" - for callback_id in self.advertisement_list: - logging.info("Stopping Advertisement {}".format(callback_id)) - self.dut.sl4a.bleStopBleAdvertising(callback_id) - time.sleep(1) - self.advertisement_list = [] - - def ble_stop_advertisement(self, callback_id): - """Stop an LE advertisement""" - if not callback_id: - logging.info("Need a callback ID") - return - callback_id = int(callback_id) - if callback_id not in self.advertisement_list: - logging.info("Callback not in list of advertisements.") - return - self.dut.sl4a.bleStopBleAdvertising(callback_id) - self.advertisement_list.remove(callback_id) - - def start_max_advertisements(self, line): - scan_response = None - if line: - scan_response = bool(line) - while (True): - try: - self.dut.sl4a.bleSetAdvertiseSettingsAdvertiseMode(ble_advertise_settings_modes['low_latency']) - self.dut.sl4a.bleSetAdvertiseSettingsIsConnectable(True) - advertise_callback, advertise_data, advertise_settings = (generate_ble_advertise_objects(self.dut.sl4a)) - if scan_response: - self.dut.sl4a.bleStartBleAdvertisingWithScanResponse(advertise_callback, advertise_data, - advertise_settings, advertise_data) - else: - self.dut.sl4a.bleStartBleAdvertising(advertise_callback, advertise_data, advertise_settings) - if self._verify_ble_adv_started(advertise_callback): - logging.info("Tracking Callback ID: {}".format(advertise_callback)) - self.advertisement_list.append(advertise_callback) - logging.info(self.advertisement_list) - else: - logging.info("Advertisements active: {}".format(len(self.advertisement_list))) - return False - except Exception as err: - logging.info("Advertisements active: {}".format(len(self.advertisement_list))) - return True diff --git a/system/blueberry/tests/gd_sl4a/lib/bt_constants.py b/system/blueberry/tests/gd_sl4a/lib/bt_constants.py deleted file mode 100644 index 3ea669db97a..00000000000 --- a/system/blueberry/tests/gd_sl4a/lib/bt_constants.py +++ /dev/null @@ -1,472 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2016 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. - -### Generic Constants Begin ### - -bt_default_timeout = 15 -default_rfcomm_timeout_ms = 10000 -default_bluetooth_socket_timeout_ms = 10000 -pan_connect_timeout = 5 -bt_discovery_timeout = 3 -small_timeout = 0.0001 - -# Time delay (in seconds) at the end of each LE CoC Test to give sufficient time -# for the ACL LE link to be disconnected. The ACL link stays connected after -# L2CAP disconnects. An example of the timeout is L2CAP_LINK_INACTIVITY_TOUT. -# This delay must be greater than the maximum of these timeouts. -# TODO: Investigate the use of broadcast intent -# BluetoothDevice.ACTION_ACL_DISCONNECTED to replace this delay method. -l2cap_max_inactivity_delay_after_disconnect = 5 - -# LE specifications related constants -le_connection_interval_time_step_ms = 1.25 -le_default_supervision_timeout = 2000 -default_le_data_length = 23 -default_le_connection_interval_ms = 30 -le_connection_event_time_step_ms = 0.625 - -# Headers of LE L2CAP Connection-oriented Channels. See section 3.4, Vol -# 3, Part A, Version 5.0. -l2cap_header_size = 4 -l2cap_coc_sdu_length_field_size = 2 -l2cap_coc_header_size = l2cap_header_size + l2cap_coc_sdu_length_field_size - -java_integer = {"min": -2147483648, "max": 2147483647} - -btsnoop_log_path_on_device = "/data/misc/bluetooth/logs/btsnoop_hci.log" -btsnoop_last_log_path_on_device = \ - "/data/misc/bluetooth/logs/btsnoop_hci.log.last" -pairing_variant_passkey_confirmation = 2 - -# Callback strings -scan_result = "BleScan{}onScanResults" -scan_failed = "BleScan{}onScanFailed" -batch_scan_result = "BleScan{}onBatchScanResult" -adv_fail = "BleAdvertise{}onFailure" -adv_succ = "BleAdvertise{}onSuccess" -bluetooth_off = "BluetoothStateChangedOff" -bluetooth_on = "BluetoothStateChangedOn" -mtu_changed = "GattConnect{}onMtuChanged" -advertising_set_started = "AdvertisingSet{}onAdvertisingSetStarted" -advertising_set_stopped = "AdvertisingSet{}onAdvertisingSetStopped" -advertising_set_on_own_address_read = "AdvertisingSet{}onOwnAddressRead" -advertising_set_enabled = "AdvertisingSet{}onAdvertisingEnabled" -advertising_set_data_set = "AdvertisingSet{}onAdvertisingDataSet" -advertising_set_scan_response_set = "AdvertisingSet{}onScanResponseDataSet" -advertising_set_parameters_update = \ - "AdvertisingSet{}onAdvertisingParametersUpdated" -advertising_set_periodic_parameters_updated = \ - "AdvertisingSet{}onPeriodicAdvertisingParametersUpdated" -advertising_set_periodic_data_set = \ - "AdvertisingSet{}onPeriodicAdvertisingDataSet" -advertising_set_periodic_enable = "AdvertisingSet{}onPeriodicAdvertisingEnable" -bluetooth_profile_connection_state_changed = \ - "BluetoothProfileConnectionStateChanged" -bluetooth_le_on = "BleStateChangedOn" -bluetooth_le_off = "BleStateChangedOff" -bluetooth_a2dp_codec_config_changed = "BluetoothA2dpCodecConfigChanged" -# End Callback Strings - -batch_scan_not_supported_list = [ - "Nexus 4", - "Nexus 5", - "Nexus 7", -] - -### Generic Constants End ### - -### Bluetooth Constants Begin ### - -# rfcomm test uuids -rfcomm_secure_uuid = "fa87c0d0-afac-11de-8a39-0800200c9a66" -rfcomm_insecure_uuid = "8ce255c0-200a-11e0-ac64-0800200c9a66" - -# bluetooth socket connection test uuid -bluetooth_socket_conn_test_uuid = "12345678-1234-5678-9abc-123456789abc" - -# Bluetooth Adapter Scan Mode Types -bt_scan_mode_types = {"state_off": -1, "none": 0, "connectable": 1, "connectable_discoverable": 3} - -# Bluetooth Adapter State Constants -bt_adapter_states = { - "off": 10, - "turning_on": 11, - "on": 12, - "turning_off": 13, - "ble_turning_on": 14, - "ble_on": 15, - "ble_turning_off": 16 -} - -# Should be kept in sync with BluetoothProfile.java -bt_profile_constants = { - "headset": 1, - "a2dp": 2, - "health": 3, - "input_device": 4, - "pan": 5, - "pbap_server": 6, - "gatt": 7, - "gatt_server": 8, - "map": 9, - "sap": 10, - "a2dp_sink": 11, - "avrcp_controller": 12, - "headset_client": 16, - "pbap_client": 17, - "map_mce": 18 -} - -# Bluetooth RFCOMM UUIDs as defined by the SIG -bt_rfcomm_uuids = { - "default_uuid": "457807c0-4897-11df-9879-0800200c9a66", - "base_uuid": "00000000-0000-1000-8000-00805F9B34FB", - "sdp": "00000001-0000-1000-8000-00805F9B34FB", - "udp": "00000002-0000-1000-8000-00805F9B34FB", - "rfcomm": "00000003-0000-1000-8000-00805F9B34FB", - "tcp": "00000004-0000-1000-8000-00805F9B34FB", - "tcs_bin": "00000005-0000-1000-8000-00805F9B34FB", - "tcs_at": "00000006-0000-1000-8000-00805F9B34FB", - "att": "00000007-0000-1000-8000-00805F9B34FB", - "obex": "00000008-0000-1000-8000-00805F9B34FB", - "ip": "00000009-0000-1000-8000-00805F9B34FB", - "ftp": "0000000A-0000-1000-8000-00805F9B34FB", - "http": "0000000C-0000-1000-8000-00805F9B34FB", - "wsp": "0000000E-0000-1000-8000-00805F9B34FB", - "bnep": "0000000F-0000-1000-8000-00805F9B34FB", - "upnp": "00000010-0000-1000-8000-00805F9B34FB", - "hidp": "00000011-0000-1000-8000-00805F9B34FB", - "hardcopy_control_channel": "00000012-0000-1000-8000-00805F9B34FB", - "hardcopy_data_channel": "00000014-0000-1000-8000-00805F9B34FB", - "hardcopy_notification": "00000016-0000-1000-8000-00805F9B34FB", - "avctp": "00000017-0000-1000-8000-00805F9B34FB", - "avdtp": "00000019-0000-1000-8000-00805F9B34FB", - "cmtp": "0000001B-0000-1000-8000-00805F9B34FB", - "mcap_control_channel": "0000001E-0000-1000-8000-00805F9B34FB", - "mcap_data_channel": "0000001F-0000-1000-8000-00805F9B34FB", - "l2cap": "00000100-0000-1000-8000-00805F9B34FB" -} - -# Should be kept in sync with BluetoothProfile#STATE_* constants. -bt_profile_states = {"disconnected": 0, "connecting": 1, "connected": 2, "disconnecting": 3} - -# Access Levels from BluetoothDevice. -bt_access_levels = {"access_allowed": 1, "access_denied": 2} - -# Priority levels as defined in BluetoothProfile.java. -bt_priority_levels = {"auto_connect": 1000, "on": 100, "off": 0, "undefined": -1} - -# A2DP codec configuration constants as defined in -# frameworks/base/core/java/android/bluetooth/BluetoothCodecConfig.java -codec_types = {'SBC': 0, 'AAC': 1, 'APTX': 2, 'APTX-HD': 3, 'LDAC': 4, 'MAX': 5, 'INVALID': 1000000} - -codec_priorities = {'DISABLED': -1, 'DEFAULT': 0, 'HIGHEST': 1000000} - -sample_rates = { - 'NONE': 0, - '44100': 0x1 << 0, - '48000': 0x1 << 1, - '88200': 0x1 << 2, - '96000': 0x1 << 3, - '176400': 0x1 << 4, - '192000': 0x1 << 5 -} - -bits_per_samples = {'NONE': 0, '16': 0x1 << 0, '24': 0x1 << 1, '32': 0x1 << 2} - -channel_modes = {'NONE': 0, 'MONO': 0x1 << 0, 'STEREO': 0x1 << 1} - -# Bluetooth HID constants. -hid_connection_timeout = 5 - -# Bluetooth HID EventFacade constants. -hid_on_set_report_event = "onSetReport" -hid_on_get_report_event = "onGetReport" -hid_on_set_protocol_event = "onSetProtocol" -hid_on_intr_data_event = "onInterruptData" -hid_on_virtual_cable_unplug_event = "onVirtualCableUnplug" -hid_id_keyboard = 1 -hid_id_mouse = 2 -hid_default_event_timeout = 15 -hid_default_set_report_payload = "Haha" - -### Bluetooth Constants End ### - -### Bluetooth Low Energy Constants Begin ### - -# Bluetooth Low Energy address types -ble_address_types = {"public": 0, "random": 1} - -# Bluetooth Low Energy scan callback types -ble_scan_settings_callback_types = {"all_matches": 1, "first_match": 2, "match_lost": 4, "found_and_lost": 6} - -# Bluetooth Low Energy scan settings match mode -ble_scan_settings_match_modes = {"aggresive": 1, "sticky": 2} - -# Bluetooth Low Energy scan settings match nums -ble_scan_settings_match_nums = {"one": 1, "few": 2, "max": 3} - -# Bluetooth Low Energy scan settings result types -ble_scan_settings_result_types = {"full": 0, "abbreviated": 1} - -# Bluetooth Low Energy scan settings mode -ble_scan_settings_modes = { - "opportunistic": -1, - "low_power": 0, - "balanced": 1, - "low_latency": 2, - "ambient_discovery": 3, -} - -# Bluetooth Low Energy scan settings report delay millis -ble_scan_settings_report_delay_milli_seconds = {"min": 0, "max": 9223372036854775807} - -# Bluetooth Low Energy scan settings phy -ble_scan_settings_phys = {"1m": 1, "2m": 2, "coded": 3, "all_supported": 255} - -# Bluetooth Low Energy advertise settings types -ble_advertise_settings_types = {"non_connectable": 0, "connectable": 1} - -# Bluetooth Low Energy advertise settings modes -ble_advertise_settings_modes = {"low_power": 0, "balanced": 1, "low_latency": 2} - -# Bluetooth Low Energy advertise settings tx power -ble_advertise_settings_tx_powers = {"ultra_low": 0, "low": 1, "medium": 2, "high": 3} - -# Bluetooth Low Energy service uuids for specific devices -ble_uuids = {"p_service": "0000feef-0000-1000-8000-00805f9b34fb", "hr_service": "0000180d-0000-1000-8000-00805f9b34fb"} - -# Bluetooth Low Energy advertising error codes -ble_advertise_error_code = { - "data_too_large": 1, - "too_many_advertisers": 2, - "advertisement_already_started": 3, - "bluetooth_internal_failure": 4, - "feature_not_supported": 5 -} - -### Bluetooth Low Energy Constants End ### - -### Chameleon Constants Begin ### - -# Chameleon audio bits per sample. -audio_bits_per_sample_16 = 16 -audio_bits_per_sample_24 = 24 -audio_bits_per_sample_32 = 32 - -# Chameleon audio sample rates. -audio_sample_rate_44100 = 44100 -audio_sample_rate_48000 = 48000 -audio_sample_rate_88200 = 88200 -audio_sample_rate_96000 = 96000 - -# Chameleon audio channel modes. -audio_channel_mode_mono = 1 -audio_channel_mode_stereo = 2 -audio_channel_mode_8 = 8 - -# Chameleon time delays. -delay_after_binding_seconds = 0.5 -delay_before_record_seconds = 0.5 -silence_wait_seconds = 5 - -# Chameleon bus endpoints. -fpga_linein_bus_endpoint = 'Chameleon FPGA line-in' -headphone_bus_endpoint = 'Cros device headphone' - -### Chameleon Constants End ### - -# Begin logcat strings dict""" -logcat_strings = { - "media_playback_vol_changed": "onRouteVolumeChanged", -} - -# End logcat strings dict""" - -### Begin Service Discovery UUIDS ### -# Values match the Bluetooth SIG defined values: """ -""" https://www.bluetooth.com/specifications/assigned-numbers/service-discovery """ -sig_uuid_constants = { - "BASE_UUID": "0000{}-0000-1000-8000-00805F9B34FB", - "SDP": "0001", - "UDP": "0002", - "RFCOMM": "0003", - "TCP": "0004", - "TCS-BIN": "0005", - "TCS-AT": "0006", - "ATT": "0007", - "OBEX": "0008", - "IP": "0009", - "FTP": "000A", - "HTTP": "000C", - "WSP": "000E", - "BNEP": "000F", - "UPNP": "0010", - "HIDP": "0011", - "HardcopyControlChannel": "0012", - "HardcopyDataChannel": "0014", - "HardcopyNotification": "0016", - "AVCTP": "0017", - "AVDTP": "0019", - "CMTP": "001B", - "MCAPControlChannel": "001E", - "MCAPDataChannel": "001F", - "L2CAP": "0100", - "ServiceDiscoveryServerServiceClassID": "1000", - "BrowseGroupDescriptorServiceClassID": "1001", - "SerialPort": "1101", - "LANAccessUsingPPP": "1102", - "DialupNetworking": "1103", - "IrMCSync": "1104", - "OBEXObjectPush": "1105", - "OBEXFileTransfer": "1106", - "IrMCSyncCommand": "1107", - "Headset": "1108", - "CordlessTelephony": "1109", - "AudioSource": "110A", - "AudioSink": "110B", - "A/V_RemoteControlTarget": "110C", - "AdvancedAudioDistribution": "110D", - "A/V_RemoteControl": "110E", - "A/V_RemoteControlController": "110F", - "Intercom": "1110", - "Fax": "1111", - "Headset - Audio Gateway (AG)": "1112", - "WAP": "1113", - "WAP_CLIENT": "1114", - "PANU": "1115", - "NAP": "1116", - "GN": "1117", - "DirectPrinting": "1118", - "ReferencePrinting": "1119", - "ImagingResponder": "111B", - "ImagingAutomaticArchive": "111C", - "ImagingReferencedObjects": "111D", - "Handsfree": "111E", - "HandsfreeAudioGateway": "111F", - "DirectPrintingReferenceObjectsService": "1120", - "ReflectedUI": "1121", - "BasicPrinting": "1122", - "PrintingStatus": "1123", - "HumanInterfaceDeviceService": "1124", - "HardcopyCableReplacement": "1125", - "HCR_Print": "1126", - "HCR_Scan": "1127", - "Common_ISDN_Access": "1128", - "SIM_Access": "112D", - "Phonebook Access - PCE": "112E", - "Phonebook Access - PSE": "112F", - "Phonebook Access": "1130", - "Headset - HS": "1131", - "Message Access Server": "1132", - "Message Notification Server": "1133", - "Message Access Profile": "1134", - "GNSS": "1135", - "GNSS_Server": "1136", - "PnPInformation": "1200", - "GenericNetworking": "1201", - "GenericFileTransfer": "1202", - "GenericAudio": "1203", - "GenericTelephony": "1204", - "UPNP_Service": "1205", - "UPNP_IP_Service": "1206", - "ESDP_UPNP_IP_PAN": "1300", - "ESDP_UPNP_IP_LAP": "1301", - "ESDP_UPNP_L2CAP": "1302", - "VideoSource": "1303", - "VideoSink": "1304", - "VideoDistribution": "1305", - "HDP": "1400" -} - -### End Service Discovery UUIDS ### - -### Begin Appearance Constants ### -# https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.gap.appearance.xml -sig_appearance_constants = { - "UNKNOWN": 0, - "PHONE": 64, - "COMPUTER": 128, - "WATCH": 192, - "WATCH_SPORTS": 193, - "CLOCK": 256, - "DISPLAY": 320, - "REMOTE_CONTROL": 384, - "EYE_GLASSES": 448, - "TAG": 512, - "KEYRING": 576, - "MEDIA_PLAYER": 640, - "BARCODE_SCANNER": 704, - "THERMOMETER": 768, - "THERMOMETER_EAR": 769, - "HEART_RATE_SENSOR": 832, - "HEART_RATE_SENSOR_BELT": 833, - "BLOOD_PRESSURE": 896, - "BLOOD_PRESSURE_ARM": 897, - "BLOOD_PRESSURE_WRIST": 898, - "HID": 960, - "HID_KEYBOARD": 961, - "HID_MOUSE": 962, - "HID_JOYSTICK": 963, - "HID_GAMEPAD": 964, - "HID_DIGITIZER_TABLET": 965, - "HID_CARD_READER": 966, - "HID_DIGITAL_PEN": 967, - "HID_BARCODE_SCANNER": 968, - "GLUCOSE_METER": 1024, - "RUNNING_WALKING_SENSOR": 1088, - "RUNNING_WALKING_SENSOR_IN_SHOE": 1089, - "RUNNING_WALKING_SENSOR_ON_SHOE": 1090, - "RUNNING_WALKING_SENSOR_ON_HIP": 1091, - "CYCLING": 1152, - "CYCLING_COMPUTER": 1153, - "CYCLING_SPEED_SENSOR": 1154, - "CYCLING_CADENCE_SENSOR": 1155, - "CYCLING_POWER_SENSOR": 1156, - "CYCLING_SPEED_AND_CADENCE_SENSOR": 1157, - "PULSE_OXIMETER": 3136, - "PULSE_OXIMETER_FINGERTIP": 3137, - "PULSE_OXIMETER_WRIST": 3138, - "WEIGHT_SCALE": 3200, - "PERSONAL_MOBILITY": 3264, - "PERSONAL_MOBILITY_WHEELCHAIR": 3265, - "PERSONAL_MOBILITY_SCOOTER": 3266, - "GLUCOSE_MONITOR": 3328, - "SPORTS_ACTIVITY": 5184, - "SPORTS_ACTIVITY_LOCATION_DISPLAY": 5185, - "SPORTS_ACTIVITY_LOCATION_AND_NAV_DISPLAY": 5186, - "SPORTS_ACTIVITY_LOCATION_POD": 5187, - "SPORTS_ACTIVITY_LOCATION_AND_NAV_POD": 5188, -} - -### End Appearance Constants ### - -# Attribute Record values from the Bluetooth Specification -# Version 5, Vol 3, Part B -bt_attribute_values = { - 'ATTR_SERVICE_RECORD_HANDLE': 0x0000, - 'ATTR_SERVICE_CLASS_ID_LIST': 0x0001, - 'ATTR_SERVICE_RECORD_STATE': 0x0002, - 'ATTR_SERVICE_ID': 0x0003, - 'ATTR_PROTOCOL_DESCRIPTOR_LIST': 0x0004, - 'ATTR_ADDITIONAL_PROTOCOL_DESCRIPTOR_LIST': 0x000D, - 'ATTR_BROWSE_GROUP_LIST': 0x0005, - 'ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST': 0x0006, - 'ATTR_SERVICE_INFO_TIME_TO_LIVE': 0x0007, - 'ATTR_SERVICE_AVAILABILITY': 0x0008, - 'ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST': 0x0009, - 'ATTR_A2DP_SUPPORTED_FEATURES': 0x0311, -} diff --git a/system/blueberry/tests/gd_sl4a/lib/gd_sl4a_base_test.py b/system/blueberry/tests/gd_sl4a/lib/gd_sl4a_base_test.py deleted file mode 100644 index b2e4e74a858..00000000000 --- a/system/blueberry/tests/gd_sl4a/lib/gd_sl4a_base_test.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2021 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import traceback -import os -import logging - -from functools import wraps -from grpc import RpcError - -from mobly import signals -from mobly.base_test import BaseTestClass -from mobly.controllers.android_device_lib.adb import AdbError -from mobly.controllers import android_device -from mobly.controllers.android_device import MOBLY_CONTROLLER_CONFIG_NAME as ANDROID_DEVICE_COFNIG_NAME - -from blueberry.utils.mobly_sl4a_utils import setup_sl4a -from blueberry.utils.mobly_sl4a_utils import teardown_sl4a -from blueberry.tests.gd.cert.context import get_current_context -from blueberry.tests.gd.cert.gd_device import MOBLY_CONTROLLER_CONFIG_NAME as GD_DEVICE_CONFIG_NAME -from blueberry.tests.gd_sl4a.lib.ble_lib import enable_bluetooth, disable_bluetooth, BleLib -from blueberry.facade import rootservice_pb2 as facade_rootservice -from blueberry.tests.gd.cert import gd_device -from blueberry.utils.bt_test_utils import clear_bonded_devices - - -class GdSl4aBaseTestClass(BaseTestClass): - - SUBPROCESS_WAIT_TIMEOUT_SECONDS = 10 - - def setup_class(self, cert_module): - self.log_path_base = get_current_context().get_full_output_path() - self.verbose_mode = bool(self.user_params.get('verbose_mode', False)) - for config in self.controller_configs[GD_DEVICE_CONFIG_NAME]: - config['verbose_mode'] = self.verbose_mode - self.cert_module = cert_module - - # Parse and construct GD device objects - self.gd_devices = self.register_controller(gd_device, required=True) - self.cert = self.gd_devices[0] - - # Parse and construct Android device objects - self.android_devices = self.register_controller(android_device, required=True) - server_port = int(self.controller_configs[ANDROID_DEVICE_COFNIG_NAME][0]['server_port']) - forwarded_port = int(self.controller_configs[ANDROID_DEVICE_COFNIG_NAME][0]['forwarded_port']) - self.dut = self.android_devices[0] - setup_sl4a(self.dut, server_port, forwarded_port) - - # Enable full btsnoop log - self.dut.adb.root() - self.dut.adb.shell("setprop persist.bluetooth.btsnooplogmode full") - getprop_result = self.dut.adb.getprop("persist.bluetooth.btsnooplogmode") - if getprop_result is None or ("full" not in getprop_result.lower()): - self.dut.log.warning( - "Failed to enable Bluetooth Hci Snoop Logging, getprop returned {}".format(getprop_result)) - - self.ble = BleLib(dut=self.dut) - - def teardown_class(self): - teardown_sl4a(self.dut) - - def setup_test(self): - self.cert.rootservice.StartStack( - facade_rootservice.StartStackRequest(module_under_test=facade_rootservice.BluetoothModule.Value( - self.cert_module),)) - self.cert.wait_channel_ready() - - self.timer_list = [] - self.dut.ed.clear_all_events() - self.dut.sl4a.setScreenTimeout(500) - self.dut.sl4a.wakeUpNow() - - # Always start tests with Bluetooth enabled and BLE disabled. - self.dut.sl4a.bluetoothDisableBLE() - disable_bluetooth(self.dut.sl4a, self.dut.ed) - # Enable full verbose logging for Bluetooth - self.dut.adb.shell("setprop log.tag.bluetooth VERBOSE") - # Then enable Bluetooth - enable_bluetooth(self.dut.sl4a, self.dut.ed) - self.dut.sl4a.bluetoothDisableBLE() - clear_bonded_devices(self.dut) - return True - - def teardown_test(self): - clear_bonded_devices(self.dut) - # Make sure BLE is disabled and Bluetooth is disabled after test - self.dut.sl4a.bluetoothDisableBLE() - disable_bluetooth(self.dut.sl4a, self.dut.ed) - try: - self.cert.rootservice.StopStack(facade_rootservice.StopStackRequest()) - except Exception: - logging.error("Failed to stop CERT stack") - - # TODO: split cert logcat logs into individual tests - current_test_dir = get_current_context().get_full_output_path() - - # Pull DUT logs - self.pull_dut_logs(current_test_dir) - - # Pull CERT logs - self.cert.pull_logs(current_test_dir) - - def pull_dut_logs(self, base_dir): - try: - self.dut.adb.pull([ - "/data/misc/bluetooth/logs/btsnoop_hci.log", - os.path.join(base_dir, "DUT_%s_btsnoop_hci.log" % self.dut.serial) - ]) - self.dut.adb.pull([ - "/data/misc/bluedroid/bt_config.conf", - os.path.join(base_dir, "DUT_%s_bt_config.conf" % self.dut.serial) - ]) - except AdbError as error: - logging.warning("Failed to pull logs from DUT: " + str(error)) - - def __getattribute__(self, name): - attr = super().__getattribute__(name) - if not callable(attr) or not GdSl4aBaseTestClass.__is_entry_function(name): - return attr - - @wraps(attr) - def __wrapped(*args, **kwargs): - try: - return attr(*args, **kwargs) - except RpcError as e: - exception_info = "".join(traceback.format_exception(e.__class__, e, e.__traceback__)) - raise signals.TestFailure("RpcError during test\n\nRpcError:\n\n%s" % (exception_info)) - - return __wrapped - - __ENTRY_METHODS = {"setup_class", "teardown_class", "setup_test", "teardown_test"} - - @staticmethod - def __is_entry_function(name): - return name.startswith("test_") or name in GdSl4aBaseTestClass.__ENTRY_METHODS diff --git a/system/blueberry/tests/gd_sl4a/security/oob_pairing_sl4a_test.py b/system/blueberry/tests/gd_sl4a/security/oob_pairing_sl4a_test.py deleted file mode 100644 index 2cef25b5bc6..00000000000 --- a/system/blueberry/tests/gd_sl4a/security/oob_pairing_sl4a_test.py +++ /dev/null @@ -1,292 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2022 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import queue -import logging - -from google.protobuf import empty_pb2 as empty_proto - -import hci_packets as hci - -from blueberry.tests.gd_sl4a.lib import gd_sl4a_base_test -from blueberry.tests.gd_sl4a.lib.bt_constants import ble_scan_settings_phys -from blueberry.tests.gd.cert.matchers import SecurityMatchers -from blueberry.tests.gd.cert.py_le_security import PyLeSecurity -from blueberry.tests.gd.cert.truth import assertThat - -from blueberry.facade import common_pb2 as common -from blueberry.facade.hci import le_advertising_manager_facade_pb2 as le_advertising_facade -from blueberry.facade.hci import le_initiator_address_facade_pb2 as le_initiator_address_facade -from blueberry.facade.security.facade_pb2 import AdvertisingCallbackMsgType -from blueberry.facade.security.facade_pb2 import BondMsgType -from blueberry.facade.security.facade_pb2 import LeAuthRequirementsMessage -from blueberry.facade.security.facade_pb2 import LeIoCapabilityMessage -from blueberry.facade.security.facade_pb2 import LeOobDataPresentMessage -from blueberry.facade.security.facade_pb2 import UiCallbackMsg -from blueberry.facade.security.facade_pb2 import UiCallbackType -from blueberry.facade.security.facade_pb2 import UiMsgType - -from mobly import test_runner - -LeIoCapabilities = LeIoCapabilityMessage.LeIoCapabilities -LeOobDataFlag = LeOobDataPresentMessage.LeOobDataFlag - -DISPLAY_ONLY = LeIoCapabilityMessage(capabilities=LeIoCapabilities.DISPLAY_ONLY) - -OOB_NOT_PRESENT = LeOobDataPresentMessage(data_present=LeOobDataFlag.NOT_PRESENT) - - -class OobData: - - address = None - confirmation = None - randomizer = None - - def __init__(self, address, confirmation, randomizer): - self.address = address - self.confirmation = confirmation - self.randomizer = randomizer - - -class OobPairingSl4aTest(gd_sl4a_base_test.GdSl4aBaseTestClass): - # Events sent from SL4A - SL4A_EVENT_GENERATED = "GeneratedOobData" - SL4A_EVENT_ERROR = "ErrorOobData" - SL4A_EVENT_BONDED = "Bonded" - SL4A_EVENT_UNBONDED = "Unbonded" - - # Matches tBT_TRANSPORT - # Used Strings because ints were causing gRPC problems - TRANSPORT_AUTO = "0" - TRANSPORT_BREDR = "1" - TRANSPORT_LE = "2" - - def setup_class(self): - super().setup_class(cert_module='SECURITY') - self.default_timeout = 5 # seconds - - def setup_test(self): - super().setup_test() - self.cert_security = PyLeSecurity(self.cert) - - def teardown_test(self): - self.cert_security.close() - super().teardown_test() - - def __get_test_irk(self): - return bytes( - bytearray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10])) - - def _generate_sl4a_oob_data(self, transport): - logging.info("Fetching OOB data...") - self.dut.sl4a.bluetoothGenerateLocalOobData(transport) - try: - event_info = self.dut.ed.pop_event(self.SL4A_EVENT_GENERATED, self.default_timeout) - except queue.Empty as error: - logging.error("Failed to generate OOB data!") - return None - logging.info("Data received!") - logging.info(event_info["data"]) - return OobData(event_info["data"]["address_with_type"], event_info["data"]["confirmation"], - event_info["data"]["randomizer"]) - - def _generate_cert_oob_data(self, transport): - if transport == self.TRANSPORT_LE: - oob_data = self.cert.security.GetLeOutOfBandData(empty_proto.Empty()) - # GetLeOutOfBandData adds null terminator to string in C code - # (length 17) before passing back to python via gRPC where it is - # converted back to bytes. Remove the null terminator for handling - # in python test, since length is known to be 16 for - # confirmation_value and random_value - oob_data.confirmation_value = oob_data.confirmation_value[:-1] - oob_data.random_value = oob_data.random_value[:-1] - return oob_data - return None - - def _set_cert_privacy_policy_with_random_address_but_advertise_resolvable(self, irk): - # Random static address below, no random resolvable address at this point - random_address_bytes = "DD:34:02:05:5C:EE".encode() - private_policy = le_initiator_address_facade.PrivacyPolicy( - address_policy=le_initiator_address_facade.AddressPolicy.USE_RESOLVABLE_ADDRESS, - address_with_type=common.BluetoothAddressWithType( - address=common.BluetoothAddress(address=random_address_bytes), type=common.RANDOM_DEVICE_ADDRESS), - rotation_irk=irk) - self.cert.security.SetLeInitiatorAddressPolicy(private_policy) - # Bluetooth MAC address must be upper case - return random_address_bytes.decode('utf-8').upper() - - def __advertise_rpa_random_policy(self, legacy_pdus, irk): - DEVICE_NAME = 'Im_The_CERT!' - logging.info("Getting random address") - ADDRESS = self._set_cert_privacy_policy_with_random_address_but_advertise_resolvable(irk) - logging.info("Done %s" % ADDRESS) - - # Setup cert side to advertise - gap_name = hci.GapData(data_type=hci.GapDataType.COMPLETE_LOCAL_NAME, - data=list(bytes(DEVICE_NAME, encoding='utf8'))) - gap_data = le_advertising_facade.GapDataMsg(data=gap_name.serialize()) - config = le_advertising_facade.AdvertisingConfig( - advertisement=[gap_data], - interval_min=512, - interval_max=768, - advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND, - own_address_type=common.USE_RANDOM_DEVICE_ADDRESS, - channel_map=7, - filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES) - extended_config = le_advertising_facade.ExtendedAdvertisingConfig( - include_tx_power=True, - connectable=True, - legacy_pdus=legacy_pdus, - advertising_config=config, - secondary_advertising_phy=ble_scan_settings_phys["1m"]) - request = le_advertising_facade.ExtendedCreateAdvertiserRequest(config=extended_config) - logging.info("Creating %s PDU advertiser..." % ("Legacy" if legacy_pdus else "Extended")) - create_response = self.cert.hci_le_advertising_manager.ExtendedCreateAdvertiser(request) - logging.info("%s PDU advertiser created." % ("Legacy" if legacy_pdus else "Extended")) - return (ADDRESS, create_response) - - def _advertise_rpa_random_legacy_pdu(self, irk): - return self.__advertise_rpa_random_policy(True, irk) - - def _advertise_rpa_random_extended_pdu(self, irk): - return self.__advertise_rpa_random_policy(False, irk) - - def _stop_advertising(self, advertiser_id): - logging.info("Stop advertising") - remove_request = le_advertising_facade.RemoveAdvertiserRequest(advertiser_id=advertiser_id) - self.cert.hci_le_advertising_manager.RemoveAdvertiser(remove_request) - logging.info("Stopped advertising") - - def _wait_for_own_address(self): - own_address = common.BluetoothAddress() - - def get_address(event): - if event.message_type == AdvertisingCallbackMsgType.OWN_ADDRESS_READ: - nonlocal own_address - own_address = event.address.address - return True - return False - - assertThat(self.cert_security.get_advertising_callback_event_stream()).emits(get_address) - return own_address - - def _wait_for_advertising_set_started(self): - advertising_started = False - - def get_advertising_set_started(event): - if event.message_type == AdvertisingCallbackMsgType.ADVERTISING_SET_STARTED: - nonlocal advertising_started - if event.advertising_started == 1: - advertising_started = True - return True - return False - - assertThat(self.cert_security.get_advertising_callback_event_stream()).emits(get_advertising_set_started) - return advertising_started - - def _wait_for_yes_no_dialog(self): - address_with_type = common.BluetoothAddressWithType() - - def get_address_with_type(event): - if event.message_type == UiMsgType.DISPLAY_PAIRING_PROMPT: - nonlocal address_with_type - address_with_type = event.peer - return True - return False - - assertThat(self.cert_security.get_ui_stream()).emits(get_address_with_type) - return address_with_type - - def test_sl4a_classic_generate_oob_data(self): - oob_data = self._generate_sl4a_oob_data(self.TRANSPORT_BREDR) - logging.info("OOB data received") - logging.info(oob_data) - assertThat(oob_data).isNotNone() - - def test_sl4a_classic_generate_oob_data_twice(self): - self.test_sl4a_classic_generate_oob_data() - self.test_sl4a_classic_generate_oob_data() - - def test_sl4a_ble_generate_oob_data(self): - oob_data = self._generate_sl4a_oob_data(self.TRANSPORT_LE) - assertThat(oob_data).isNotNone() - - def test_cert_ble_generate_oob_data(self): - oob_data = self._generate_cert_oob_data(self.TRANSPORT_LE) - assertThat(oob_data).isNotNone() - - def _bond_sl4a_cert_oob(self): - self.cert.security.SetLeIoCapability(DISPLAY_ONLY) - self.cert.security.SetLeOobDataPresent(OOB_NOT_PRESENT) - self.cert.security.SetLeAuthRequirements(LeAuthRequirementsMessage(bond=1, mitm=1, secure_connections=1)) - - RANDOM_ADDRESS, create_response = self._advertise_rpa_random_extended_pdu(self.__get_test_irk()) - - self._wait_for_advertising_set_started() - - get_own_address_request = le_advertising_facade.GetOwnAddressRequest( - advertiser_id=create_response.advertiser_id) - self.cert.hci_le_advertising_manager.GetOwnAddress(get_own_address_request) - advertising_address = self._wait_for_own_address() - - oob_data = self._generate_cert_oob_data(self.TRANSPORT_LE) - assertThat(oob_data).isNotNone() - - self.dut.sl4a.bluetoothCreateBondOutOfBand( - advertising_address.decode("utf-8").upper(), self.TRANSPORT_LE, oob_data.confirmation_value.hex(), - oob_data.random_value.hex()) - - address_with_type = self._wait_for_yes_no_dialog() - self.cert.security.SendUiCallback( - UiCallbackMsg(message_type=UiCallbackType.PAIRING_PROMPT, - boolean=True, - unique_id=1, - address=address_with_type)) - - assertThat(self.cert_security.get_bond_stream()).emits(SecurityMatchers.BondMsg(BondMsgType.DEVICE_BONDED)) - - try: - bond_state = self.dut.ed.pop_event(self.SL4A_EVENT_BONDED, self.default_timeout) - except queue.Empty as error: - logging.error("Failed to get bond event!") - - assertThat(bond_state).isNotNone() - logging.info("Bonded: %s", bond_state["data"]["bonded_state"]) - assertThat(bond_state["data"]["bonded_state"]).isEqualTo(True) - self._stop_advertising(create_response.advertiser_id) - return (RANDOM_ADDRESS, advertising_address) - - def test_sl4a_create_bond_out_of_band(self): - self._bond_sl4a_cert_oob() - - def test_generate_oob_after_pairing(self): - self._bond_sl4a_cert_oob() - assertThat(self._generate_sl4a_oob_data(self.TRANSPORT_LE)).isNotNone() - - def test_remove_bond(self): - self.dut.sl4a.bluetoothUnbond(self._bond_sl4a_cert_oob()[1].decode().upper()) - bond_state = None - try: - bond_state = self.dut.ed.pop_event(self.SL4A_EVENT_UNBONDED, self.default_timeout) - except queue.Empty as error: - logging.error("Failed to get bond event!") - - assertThat(bond_state).isNotNone() - assertThat(bond_state["data"]["bonded_state"]).isEqualTo(False) - - -if __name__ == '__main__': - test_runner.main() -- GitLab From 931fab3a92130960526f2db4ec22d13ff6cf54e8 Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Mon, 17 Jun 2024 17:50:26 -0700 Subject: [PATCH 0051/1446] gd/cert: Remove PyLeSecurity helper Unused after removing the GD SL4a tests Bug: 333555245 Test: None Flag: EXEMPT, dead code removal Change-Id: I43c26adc1e456602b2350909f0d945cd9076b88f --- system/blueberry/tests/gd/cert/gd_device.py | 2 - .../blueberry/tests/gd/cert/py_le_security.py | 80 ------------------- 2 files changed, 82 deletions(-) delete mode 100644 system/blueberry/tests/gd/cert/py_le_security.py diff --git a/system/blueberry/tests/gd/cert/gd_device.py b/system/blueberry/tests/gd/cert/gd_device.py index f5d5c5030cb..99077d470f6 100644 --- a/system/blueberry/tests/gd/cert/gd_device.py +++ b/system/blueberry/tests/gd/cert/gd_device.py @@ -55,7 +55,6 @@ from blueberry.facade.hci import le_scanning_manager_facade_pb2_grpc from blueberry.facade.l2cap.classic import facade_pb2_grpc as l2cap_facade_pb2_grpc from blueberry.facade.l2cap.le import facade_pb2_grpc as l2cap_le_facade_pb2_grpc from blueberry.facade.neighbor import facade_pb2_grpc as neighbor_facade_pb2_grpc -from blueberry.facade.security import facade_pb2_grpc as security_facade_pb2_grpc from mobly import utils from mobly.controllers.android_device_lib.adb import AdbError @@ -259,7 +258,6 @@ class GdDeviceBase(ABC): self.hci_le_scanning_manager = le_scanning_manager_facade_pb2_grpc.LeScanningManagerFacadeStub( self.grpc_channel) self.neighbor = neighbor_facade_pb2_grpc.NeighborFacadeStub(self.grpc_channel) - self.security = security_facade_pb2_grpc.SecurityModuleFacadeStub(self.grpc_channel) def get_crash_snippet_and_log_tail(self): if is_subprocess_alive(self.backing_process): diff --git a/system/blueberry/tests/gd/cert/py_le_security.py b/system/blueberry/tests/gd/cert/py_le_security.py deleted file mode 100644 index d33d2552681..00000000000 --- a/system/blueberry/tests/gd/cert/py_le_security.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2020 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging - -from blueberry.tests.gd.cert.closable import Closable -from blueberry.tests.gd.cert.closable import safeClose -from blueberry.tests.gd.cert.event_stream import EventStream -from blueberry.tests.gd.cert.matchers import SecurityMatchers -from blueberry.tests.gd.cert.truth import assertThat -from datetime import timedelta -from google.protobuf import empty_pb2 as empty_proto -from blueberry.facade.security.facade_pb2 import LeAuthRequirementsMessage -from blueberry.facade.security.facade_pb2 import HelperMsgType - - -class PyLeSecurity(Closable): - """ - Abstraction for security tasks and GRPC calls - """ - - _ui_event_stream = None - _bond_event_stream = None - _helper_event_stream = None - - def __init__(self, device): - logging.info("DUT: Init") - self._device = device - self._device.wait_channel_ready() - self._ui_event_stream = EventStream(self._device.security.FetchUiEvents(empty_proto.Empty())) - self._bond_event_stream = EventStream(self._device.security.FetchBondEvents(empty_proto.Empty())) - self._helper_event_stream = EventStream(self._device.security.FetchHelperEvents(empty_proto.Empty())) - self._advertising_callback_event_stream = EventStream( - self._device.security.FetchAdvertisingCallbackEvents(empty_proto.Empty())) - - def get_ui_stream(self): - return self._ui_event_stream - - def get_bond_stream(self): - return self._bond_event_stream - - def get_advertising_callback_event_stream(self): - return self._advertising_callback_event_stream - - def SetLeAuthRequirements(self, *args, **kwargs): - return self._device.security.SetLeAuthRequirements(LeAuthRequirementsMessage(*args, **kwargs)) - - def close(self): - if self._ui_event_stream is not None: - safeClose(self._ui_event_stream) - else: - logging.info("DUT: UI Event Stream is None!") - - if self._bond_event_stream is not None: - safeClose(self._bond_event_stream) - else: - logging.info("DUT: Bond Event Stream is None!") - - if self._helper_event_stream is not None: - safeClose(self._helper_event_stream) - else: - logging.info("DUT: Helper Event Stream is None!") - - if self._advertising_callback_event_stream is not None: - safeClose(self._advertising_callback_event_stream) - else: - logging.info("DUT: Advertising Callback Event Stream is None!") -- GitLab From 40d33581d1775c71bc3d85ef8d233b564abb50e1 Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Fri, 14 Jun 2024 15:05:16 -0700 Subject: [PATCH 0052/1446] btif_av: Make public the methods from btav_source_interface_t The interfaces btif_av_get_src_interface() and get_profile_interface(("a2dp") are not used except in the JNI layer. The call to get_profile_interface in com_android_bluetooth_a2dp is removed in order to de-obfuscate the call graph for a2dp. The inferface type and declaration is also removed now that it is unused. Bug: 331817295 Test: m com.android.btservices Flag: EXEMPT, no logical change Change-Id: I358b84fb3a3d479965185f8537c240a28c6c06f6 --- .../app/jni/com_android_bluetooth_a2dp.cpp | 88 +++++-------------- system/btif/include/btif_av.h | 49 ++++++----- system/btif/src/bluetooth.cc | 4 - system/btif/src/btif_a2dp.cc | 2 +- system/btif/src/btif_av.cc | 49 +++-------- system/gd/rust/topshim/btav/btav_shim.cc | 18 ++-- system/gd/rust/topshim/btav/btav_shim.h | 5 +- system/include/hardware/bt_av.h | 38 +------- system/test/mock/mock_btif_av.cc | 12 --- system/test/mock/mock_btif_av.h | 21 ----- 10 files changed, 74 insertions(+), 212 deletions(-) diff --git a/android/app/jni/com_android_bluetooth_a2dp.cpp b/android/app/jni/com_android_bluetooth_a2dp.cpp index 6d73056c223..3d9af106ed9 100644 --- a/android/app/jni/com_android_bluetooth_a2dp.cpp +++ b/android/app/jni/com_android_bluetooth_a2dp.cpp @@ -14,12 +14,12 @@ * limitations under the License. */ -#define LOG_TAG "BluetoothA2dpServiceJni" - -#include +#define LOG_TAG "bluetooth-a2dp" +#include #include +#include "btif/include/btif_av.h" #include "btif/include/btif_util.h" #include "com_android_bluetooth.h" #include "hardware/bt_av.h" @@ -44,7 +44,6 @@ static struct { jmethodID getCodecSpecific4; } android_bluetooth_BluetoothCodecConfig; -static const btav_source_interface_t* sBluetoothA2dpInterface = nullptr; static std::vector supported_codecs; static std::shared_timed_mutex interface_mutex; @@ -261,11 +260,8 @@ static void initNative(JNIEnv* env, jobject object, return; } - if (sBluetoothA2dpInterface != nullptr) { - log::warn("Cleaning up A2DP Interface before initializing..."); - sBluetoothA2dpInterface->cleanup(); - sBluetoothA2dpInterface = nullptr; - } + log::warn("Cleaning up A2DP Interface before initializing..."); + btif_av_source_cleanup(); if (mCallbacksObj != nullptr) { log::warn("Cleaning up A2DP callback object"); @@ -285,27 +281,18 @@ static void initNative(JNIEnv* env, jobject object, return; } - sBluetoothA2dpInterface = - (btav_source_interface_t*)btInf->get_profile_interface( - BT_PROFILE_ADVANCED_AUDIO_ID); - if (sBluetoothA2dpInterface == nullptr) { - log::error("Failed to get Bluetooth A2DP Interface"); - return; - } - std::vector codec_priorities = prepareCodecPreferences(env, object, codecConfigArray); std::vector codec_offloading = prepareCodecPreferences(env, object, codecOffloadingArray); - bt_status_t status = sBluetoothA2dpInterface->init( + bt_status_t status = btif_av_source_init( &sBluetoothA2dpCallbacks, maxConnectedAudioDevices, codec_priorities, codec_offloading, &supported_codecs); if (status != BT_STATUS_SUCCESS) { log::error("Failed to initialize Bluetooth A2DP, status: {}", bt_status_text(status)); - sBluetoothA2dpInterface = nullptr; return; } } @@ -320,10 +307,7 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { return; } - if (sBluetoothA2dpInterface != nullptr) { - sBluetoothA2dpInterface->cleanup(); - sBluetoothA2dpInterface = nullptr; - } + btif_av_source_cleanup(); env->DeleteGlobalRef(android_bluetooth_BluetoothCodecConfig.clazz); android_bluetooth_BluetoothCodecConfig.clazz = nullptr; @@ -335,8 +319,6 @@ static void cleanupNative(JNIEnv* env, jobject /* object */) { } static jobjectArray getSupportedCodecTypesNative(JNIEnv* env) { - log::info("{}", fmt::ptr(sBluetoothA2dpInterface)); - jclass android_bluetooth_BluetoothCodecType_clazz = (jclass)env->NewGlobalRef( env->FindClass("android/bluetooth/BluetoothCodecType")); if (android_bluetooth_BluetoothCodecType_clazz == nullptr) { @@ -376,11 +358,6 @@ static jobjectArray getSupportedCodecTypesNative(JNIEnv* env) { static jboolean connectA2dpNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); - if (!sBluetoothA2dpInterface) { - log::error("Failed to get the Bluetooth A2DP Interface"); - return JNI_FALSE; - } - jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { jniThrowIOException(env, EINVAL); @@ -389,9 +366,9 @@ static jboolean connectA2dpNative(JNIEnv* env, jobject /* object */, RawAddress bd_addr; bd_addr.FromOctets(reinterpret_cast(addr)); - log::info("sBluetoothA2dpInterface: {}, {}", - fmt::ptr(sBluetoothA2dpInterface), bd_addr); - bt_status_t status = sBluetoothA2dpInterface->connect(bd_addr); + + log::info("{}", bd_addr); + bt_status_t status = btif_av_source_connect(bd_addr); if (status != BT_STATUS_SUCCESS) { log::error("Failed A2DP connection, status: {}", bt_status_text(status)); } @@ -402,11 +379,6 @@ static jboolean connectA2dpNative(JNIEnv* env, jobject /* object */, static jboolean disconnectA2dpNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); - if (!sBluetoothA2dpInterface) { - log::error("Failed to get the Bluetooth A2DP Interface"); - return JNI_FALSE; - } - jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { jniThrowIOException(env, EINVAL); @@ -415,9 +387,9 @@ static jboolean disconnectA2dpNative(JNIEnv* env, jobject /* object */, RawAddress bd_addr; bd_addr.FromOctets(reinterpret_cast(addr)); - log::info("sBluetoothA2dpInterface: {}, {}", - fmt::ptr(sBluetoothA2dpInterface), bd_addr); - bt_status_t status = sBluetoothA2dpInterface->disconnect(bd_addr); + + log::info("{}", bd_addr); + bt_status_t status = btif_av_source_disconnect(bd_addr); if (status != BT_STATUS_SUCCESS) { log::error("Failed A2DP disconnection, status: {}", bt_status_text(status)); } @@ -428,13 +400,8 @@ static jboolean disconnectA2dpNative(JNIEnv* env, jobject /* object */, static jboolean setSilenceDeviceNative(JNIEnv* env, jobject /* object */, jbyteArray address, jboolean silence) { std::shared_lock lock(interface_mutex); - if (!sBluetoothA2dpInterface) { - log::error("Failed to get the Bluetooth A2DP Interface"); - return JNI_FALSE; - } jbyte* addr = env->GetByteArrayElements(address, nullptr); - RawAddress bd_addr = RawAddress::kEmpty; if (addr) { bd_addr.FromOctets(reinterpret_cast(addr)); @@ -442,11 +409,9 @@ static jboolean setSilenceDeviceNative(JNIEnv* env, jobject /* object */, if (bd_addr == RawAddress::kEmpty) { return JNI_FALSE; } - log::info("sBluetoothA2dpInterface: {}, {}: silence: {}", - fmt::ptr(sBluetoothA2dpInterface), bd_addr, - static_cast(silence)); - bt_status_t status = - sBluetoothA2dpInterface->set_silence_device(bd_addr, silence); + + log::info("{}: silence={}", bd_addr, silence); + bt_status_t status = btif_av_source_set_silence_device(bd_addr, silence); if (status != BT_STATUS_SUCCESS) { log::error("Failed A2DP set_silence_device, status: {}", bt_status_text(status)); @@ -458,20 +423,15 @@ static jboolean setSilenceDeviceNative(JNIEnv* env, jobject /* object */, static jboolean setActiveDeviceNative(JNIEnv* env, jobject /* object */, jbyteArray address) { std::shared_lock lock(interface_mutex); - if (!sBluetoothA2dpInterface) { - log::error("Failed to get the Bluetooth A2DP Interface"); - return JNI_FALSE; - } jbyte* addr = env->GetByteArrayElements(address, nullptr); - RawAddress bd_addr = RawAddress::kEmpty; if (addr) { bd_addr.FromOctets(reinterpret_cast(addr)); } - log::info("sBluetoothA2dpInterface: {}, {}", - fmt::ptr(sBluetoothA2dpInterface), bd_addr); - bt_status_t status = sBluetoothA2dpInterface->set_active_device(bd_addr); + + log::info("{}", bd_addr); + bt_status_t status = btif_av_source_set_active_device(bd_addr); if (status != BT_STATUS_SUCCESS) { log::error("Failed A2DP set_active_device, status: {}", bt_status_text(status)); @@ -484,11 +444,6 @@ static jboolean setCodecConfigPreferenceNative(JNIEnv* env, jobject object, jbyteArray address, jobjectArray codecConfigArray) { std::shared_lock lock(interface_mutex); - if (!sBluetoothA2dpInterface) { - log::error("Failed to get the Bluetooth A2DP Interface"); - return JNI_FALSE; - } - jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { jniThrowIOException(env, EINVAL); @@ -499,11 +454,10 @@ static jboolean setCodecConfigPreferenceNative(JNIEnv* env, jobject object, bd_addr.FromOctets(reinterpret_cast(addr)); std::vector codec_preferences = prepareCodecPreferences(env, object, codecConfigArray); - log::info("sBluetoothA2dpInterface: {}, {}: {}", - fmt::ptr(sBluetoothA2dpInterface), bd_addr, + log::info("{}: {}", bd_addr, btav_a2dp_codec_config_t::PrintCodecs(codec_preferences)); bt_status_t status = - sBluetoothA2dpInterface->config_codec(bd_addr, codec_preferences); + btif_av_source_set_codec_config_preference(bd_addr, codec_preferences); if (status != BT_STATUS_SUCCESS) { log::error("Failed codec configuration, status: {}", bt_status_text(status)); diff --git a/system/btif/include/btif_av.h b/system/btif/include/btif_av.h index d1aa353942f..c44156beecf 100644 --- a/system/btif/include/btif_av.h +++ b/system/btif/include/btif_av.h @@ -29,13 +29,28 @@ #include "include/hardware/bt_av.h" #include "types/raw_address.h" -// #include "bta/include/bta_av_api.h" -// #include "btif/include/btif_common.h" +/* Interface methods for the A2DP source stack. */ + +bt_status_t btif_av_source_init( + btav_source_callbacks_t* callbacks, int max_connected_audio_devices, + const std::vector& codec_priorities, + const std::vector& offloading_preference, + std::vector* supported_codecs); +bt_status_t btif_av_source_connect(const RawAddress& peer_address); +bt_status_t btif_av_source_disconnect(const RawAddress& peer_address); +bt_status_t btif_av_source_set_silence_device(const RawAddress& peer_address, + bool silence); +bt_status_t btif_av_source_set_active_device(const RawAddress& peer_address); +bt_status_t btif_av_source_set_codec_config_preference( + const RawAddress& peer_address, + std::vector codec_preferences); +void btif_av_source_cleanup(); /** * Enum to represent the type of local a2dp profile. */ enum class A2dpType { kSource, kSink, kUnknown }; + /** * When the local device is A2DP source, get the address of the active peer. */ @@ -223,15 +238,6 @@ uint16_t btif_av_get_audio_delay(const A2dpType local_a2dp_type); */ void btif_av_reset_audio_delay(void); -/** - * Called to disconnect peer device when - * remote initiatied offload start failed - * - * @param peer_address to disconnect - * - */ -void btif_av_src_disconnect_sink(const RawAddress& peer_address); - /** * check A2DP offload support enabled * @param none @@ -287,14 +293,15 @@ void btif_av_connect_sink_delayed(uint8_t handle, /** * Check whether A2DP Source is enabled. */ -extern bool btif_av_is_source_enabled(void); -extern bool btif_av_both_enable(void); -extern bool btif_av_src_sink_coexist_enabled(void); -extern bool btif_av_is_sink_enabled(void); -extern bool btif_av_is_connected_addr(const RawAddress& peer_address, - const A2dpType local_a2dp_type); -extern bool btif_av_peer_is_connected_sink(const RawAddress& peer_address); -extern bool btif_av_peer_is_connected_source(const RawAddress& peer_address); -extern bool btif_av_peer_is_sink(const RawAddress& peer_address); -extern bool btif_av_peer_is_source(const RawAddress& peer_address); +bool btif_av_is_source_enabled(void); +bool btif_av_both_enable(void); +bool btif_av_src_sink_coexist_enabled(void); +bool btif_av_is_sink_enabled(void); +bool btif_av_is_connected_addr(const RawAddress& peer_address, + const A2dpType local_a2dp_type); +bool btif_av_peer_is_connected_sink(const RawAddress& peer_address); +bool btif_av_peer_is_connected_source(const RawAddress& peer_address); +bool btif_av_peer_is_sink(const RawAddress& peer_address); +bool btif_av_peer_is_source(const RawAddress& peer_address); + #endif /* BTIF_AV_H */ diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc index ffcc2f64ffc..b5b15eadbbd 100644 --- a/system/btif/src/bluetooth.cc +++ b/system/btif/src/bluetooth.cc @@ -142,7 +142,6 @@ bool is_local_device_atv = false; /* handsfree profile - client */ extern const bthf_client_interface_t* btif_hf_client_get_interface(); /* advanced audio profile */ -extern const btav_source_interface_t* btif_av_get_src_interface(); extern const btav_sink_interface_t* btif_av_get_sink_interface(); /*rfc l2cap*/ extern const btsock_interface_t* btif_sock_get_interface(); @@ -884,9 +883,6 @@ static const void* get_profile_interface(const char* profile_id) { if (is_profile(profile_id, BT_PROFILE_PAN_ID)) return btif_pan_get_interface(); - if (is_profile(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID)) - return btif_av_get_src_interface(); - if (is_profile(profile_id, BT_PROFILE_ADVANCED_AUDIO_SINK_ID)) return btif_av_get_sink_interface(); diff --git a/system/btif/src/btif_a2dp.cc b/system/btif/src/btif_a2dp.cc index 5a5f10a956c..bd4b58162c8 100644 --- a/system/btif/src/btif_a2dp.cc +++ b/system/btif/src/btif_a2dp.cc @@ -202,7 +202,7 @@ void btif_a2dp_on_offload_started(const RawAddress& peer_addr, // suspend is triggered for remote start. Disconnect only if SoC // returned failure for offload VSC log::error("peer {} offload start failed", peer_addr); - btif_av_src_disconnect_sink(peer_addr); + btif_av_source_disconnect(peer_addr); } } if (bluetooth::audio::a2dp::is_hal_enabled()) { diff --git a/system/btif/src/btif_av.cc b/system/btif/src/btif_av.cc index f7409ed7f16..83ac4fb0fa9 100644 --- a/system/btif/src/btif_av.cc +++ b/system/btif/src/btif_av.cc @@ -793,7 +793,6 @@ static BtifAvSink btif_av_sink; btif_rc_handler(e, d); \ } break; -static bt_status_t src_disconnect_sink(const RawAddress& peer_address); static bt_status_t sink_disconnect_src(const RawAddress& peer_address); static void btif_av_source_dispatch_sm_event(const RawAddress& peer_address, btif_av_sm_event_t event); @@ -1765,7 +1764,7 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { // Check whether connection is allowed if (peer_.IsSink()) { can_connect = btif_av_source.AllowedToConnect(peer_.PeerAddress()); - if (!can_connect) src_disconnect_sink(peer_.PeerAddress()); + if (!can_connect) btif_av_source_disconnect(peer_.PeerAddress()); } else if (peer_.IsSource()) { can_connect = btif_av_sink.AllowedToConnect(peer_.PeerAddress()); if (!can_connect) sink_disconnect_src(peer_.PeerAddress()); @@ -1819,7 +1818,7 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { if (btif_av_src_sink_coexist_enabled()) BTA_AvCloseRc(((tBTA_AV*)p_data)->rc_open.rc_handle); else - src_disconnect_sink(peer_.PeerAddress()); + btif_av_source_disconnect(peer_.PeerAddress()); } } else if (peer_.IsSource()) { can_connect = btif_av_sink.AllowedToConnect(peer_.PeerAddress()); @@ -1948,7 +1947,7 @@ bool BtifAvStateMachine::StateIdle::ProcessEvent(uint32_t event, void* p_data) { peer_.PeerAddress()); if (peer_.IsSink()) { - src_disconnect_sink(peer_.PeerAddress()); + btif_av_source_disconnect(peer_.PeerAddress()); } else if (peer_.IsSource()) { sink_disconnect_src(peer_.PeerAddress()); } @@ -2151,7 +2150,7 @@ bool BtifAvStateMachine::StateOpening::ProcessEvent(uint32_t event, bool can_connect = true; if (peer_.IsSink()) { can_connect = btif_av_source.AllowedToConnect(peer_.PeerAddress()); - if (!can_connect) src_disconnect_sink(peer_.PeerAddress()); + if (!can_connect) btif_av_source_disconnect(peer_.PeerAddress()); } else if (peer_.IsSource()) { can_connect = btif_av_sink.AllowedToConnect(peer_.PeerAddress()); if (!can_connect) sink_disconnect_src(peer_.PeerAddress()); @@ -2484,7 +2483,7 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event, btif_a2dp_command_ack(A2DP_CTRL_ACK_FAILURE); } if (peer_.IsSink()) { - src_disconnect_sink(peer_.PeerAddress()); + btif_av_source_disconnect(peer_.PeerAddress()); } else if (peer_.IsSource()) { sink_disconnect_src(peer_.PeerAddress()); } @@ -3495,7 +3494,7 @@ static void bta_av_sink_media_callback(const RawAddress& peer_address, } // Initializes the AV interface for source mode -static bt_status_t init_src( +bt_status_t btif_av_source_init( btav_source_callbacks_t* callbacks, int max_connected_audio_devices, const std::vector& codec_priorities, const std::vector& offloading_preference, @@ -3604,7 +3603,7 @@ static void set_active_peer_int(uint8_t peer_sep, peer_ready_promise.set_value(); } -static bt_status_t src_connect_sink(const RawAddress& peer_address) { +bt_status_t btif_av_source_connect(const RawAddress& peer_address) { log::info("peer={}", peer_address); if (!btif_av_source.Enabled()) { @@ -3630,7 +3629,7 @@ static bt_status_t sink_connect_src(const RawAddress& peer_address) { connect_int); } -static bt_status_t src_disconnect_sink(const RawAddress& peer_address) { +bt_status_t btif_av_source_disconnect(const RawAddress& peer_address) { log::info("peer={}", peer_address); if (!btif_av_source.Enabled()) { @@ -3686,8 +3685,8 @@ static bt_status_t sink_set_active_device(const RawAddress& peer_address) { return status; } -static bt_status_t src_set_silence_sink(const RawAddress& peer_address, - bool silence) { +bt_status_t btif_av_source_set_silence_device(const RawAddress& peer_address, + bool silence) { log::info("peer={} silence={}", peer_address, silence); if (!btif_av_source.Enabled()) { @@ -3700,7 +3699,7 @@ static bt_status_t src_set_silence_sink(const RawAddress& peer_address, base::BindOnce(&set_source_silence_peer_int, peer_address, silence)); } -static bt_status_t src_set_active_sink(const RawAddress& peer_address) { +bt_status_t btif_av_source_set_active_device(const RawAddress& peer_address) { log::info("peer={}", peer_address); if (!btif_av_source.Enabled()) { @@ -3722,7 +3721,7 @@ static bt_status_t src_set_active_sink(const RawAddress& peer_address) { return status; } -static bt_status_t codec_config_src( +bt_status_t btif_av_source_set_codec_config_preference( const RawAddress& peer_address, std::vector codec_preferences) { log::info("peer={} codec_preferences=[{}]", peer_address, @@ -3753,7 +3752,7 @@ static bt_status_t codec_config_src( return status; } -static void cleanup_src(void) { +void btif_av_source_cleanup(void) { log::info(""); do_in_main_thread(FROM_HERE, base::BindOnce(&BtifAvSource::Cleanup, @@ -3766,17 +3765,6 @@ static void cleanup_sink(void) { base::Unretained(&btif_av_sink))); } -static const btav_source_interface_t bt_av_src_interface = { - sizeof(btav_source_interface_t), - init_src, - src_connect_sink, - src_disconnect_sink, - src_set_silence_sink, - src_set_active_sink, - codec_config_src, - cleanup_src, -}; - static const btav_sink_interface_t bt_av_sink_interface = { sizeof(btav_sink_interface_t), init_sink, @@ -3868,12 +3856,6 @@ void btif_av_stream_start_offload(void) { BTIF_AV_OFFLOAD_START_REQ_EVT); } -void btif_av_src_disconnect_sink(const RawAddress& peer_address) { - log::info("peer={}", peer_address); - - src_disconnect_sink(peer_address); -} - bool btif_av_stream_ready(const A2dpType local_a2dp_type) { // Make sure the main adapter is enabled if (btif_is_enabled() == 0) { @@ -4014,11 +3996,6 @@ bt_status_t btif_av_sink_execute_service(bool enable) { return BT_STATUS_SUCCESS; } -// Get the AV callback interface for A2DP source profile -const btav_source_interface_t* btif_av_get_src_interface(void) { - return &bt_av_src_interface; -} - // Get the AV callback interface for A2DP sink profile const btav_sink_interface_t* btif_av_get_sink_interface(void) { return &bt_av_sink_interface; diff --git a/system/gd/rust/topshim/btav/btav_shim.cc b/system/gd/rust/topshim/btav/btav_shim.cc index 2ebed73deb6..d4806c1d050 100644 --- a/system/gd/rust/topshim/btav/btav_shim.cc +++ b/system/gd/rust/topshim/btav/btav_shim.cc @@ -20,6 +20,7 @@ #include #include "base/functional/callback.h" +#include "btif/include/btif_av.h" #include "include/hardware/avrcp/avrcp.h" #include "include/hardware/bluetooth.h" #include "rust/cxx.h" @@ -267,8 +268,7 @@ std::unique_ptr GetA2dpProfile(const unsigned char* btif) { const bt_interface_t* btif_ = reinterpret_cast(btif); - auto a2dpif = std::make_unique( - reinterpret_cast(btif_->get_profile_interface("a2dp"))); + auto a2dpif = std::make_unique(); internal::g_a2dpif = a2dpif.get(); return a2dpif; } @@ -277,31 +277,31 @@ int A2dpIntf::init() const { std::vector a; std::vector b; std::vector c; - return intf_->init(&internal::g_callbacks, 1, a, b, &c); + return btif_av_source_init(&internal::g_callbacks, 1, a, b, &c); } uint32_t A2dpIntf::connect(RawAddress addr) const { - return intf_->connect(addr); + return btif_av_source_connect(addr); } uint32_t A2dpIntf::disconnect(RawAddress addr) const { - return intf_->disconnect(addr); + return btif_av_source_disconnect(addr); } int A2dpIntf::set_silence_device(RawAddress addr, bool silent) const { - return intf_->set_silence_device(addr, silent); + return btif_av_source_set_silence_device(addr, silent); } int A2dpIntf::set_active_device(RawAddress addr) const { - return intf_->set_active_device(addr); + return btif_av_source_set_active_device(addr); } int A2dpIntf::config_codec(RawAddress addr, ::rust::Vec codec_preferences) const { std::vector prefs; for (size_t i = 0; i < codec_preferences.size(); ++i) { prefs.push_back(internal::from_rust_codec_config(codec_preferences[i])); } - return intf_->config_codec(addr, prefs); + return btif_av_source_set_codec_config_preference(addr, prefs); } void A2dpIntf::cleanup() const { - intf_->cleanup(); + btif_av_source_cleanup(); } bool A2dpIntf::set_audio_config(A2dpCodecConfig rconfig) const { bluetooth::audio::a2dp::AudioConfig config = { diff --git a/system/gd/rust/topshim/btav/btav_shim.h b/system/gd/rust/topshim/btav/btav_shim.h index aa6df9766e3..16b0e008a4a 100644 --- a/system/gd/rust/topshim/btav/btav_shim.h +++ b/system/gd/rust/topshim/btav/btav_shim.h @@ -34,7 +34,7 @@ struct RustPlayStatus; class A2dpIntf { public: - A2dpIntf(const btav_source_interface_t* intf) : intf_(intf){}; + A2dpIntf() {} ~A2dpIntf(); // interface for Settings @@ -52,9 +52,6 @@ class A2dpIntf { bool stop_audio_request() const; bool suspend_audio_request() const; RustPresentationPosition get_presentation_position() const; - - private: - const btav_source_interface_t* intf_; }; std::unique_ptr GetA2dpProfile(const unsigned char* btif); diff --git a/system/include/hardware/bt_av.h b/system/include/hardware/bt_av.h index 83d812a2949..59d5effa2b1 100644 --- a/system/include/hardware/bt_av.h +++ b/system/include/hardware/bt_av.h @@ -98,7 +98,7 @@ typedef struct { typedef enum { // Disable the codec. // NOTE: This value can be used only during initialization when - // function btav_source_interface_t::init() is called. + // function btif_av_source_init() is called. BTAV_A2DP_CODEC_PRIORITY_DISABLED = -1, // Reset the codec priority to its default value. @@ -366,42 +366,6 @@ typedef struct { * */ -/** Represents the standard BT-AV A2DP Source interface. - */ -typedef struct { - /** set to sizeof(btav_source_interface_t) */ - size_t size; - /** - * Register the BtAv callbacks. - */ - bt_status_t (*init)( - btav_source_callbacks_t* callbacks, int max_connected_audio_devices, - const std::vector& codec_priorities, - const std::vector& offloading_preference, - std::vector* supported_codecs); - - /** connect to headset */ - bt_status_t (*connect)(const RawAddress& bd_addr); - - /** dis-connect from headset */ - bt_status_t (*disconnect)(const RawAddress& bd_addr); - - /** sets the connected device silence state */ - bt_status_t (*set_silence_device)(const RawAddress& bd_addr, bool silence); - - /** sets the connected device as active */ - bt_status_t (*set_active_device)(const RawAddress& bd_addr); - - /** configure the codecs settings preferences */ - bt_status_t (*config_codec)( - const RawAddress& bd_addr, - std::vector codec_preferences); - - /** Closes the interface. */ - void (*cleanup)(void); - -} btav_source_interface_t; - /** Represents the standard BT-AV A2DP Sink interface. */ typedef struct { diff --git a/system/test/mock/mock_btif_av.cc b/system/test/mock/mock_btif_av.cc index 97ca5d3b9b8..abc971e664e 100644 --- a/system/test/mock/mock_btif_av.cc +++ b/system/test/mock/mock_btif_av.cc @@ -43,7 +43,6 @@ struct btif_av_find_by_handle btif_av_find_by_handle; struct btif_av_get_audio_delay btif_av_get_audio_delay; struct btif_av_get_peer_sep btif_av_get_peer_sep; struct btif_av_get_sink_interface btif_av_get_sink_interface; -struct btif_av_get_src_interface btif_av_get_src_interface; struct btif_av_is_a2dp_offload_enabled btif_av_is_a2dp_offload_enabled; struct btif_av_is_a2dp_offload_running btif_av_is_a2dp_offload_running; struct btif_av_is_connected btif_av_is_connected; @@ -69,7 +68,6 @@ struct btif_av_sink_active_peer btif_av_sink_active_peer; struct btif_av_sink_execute_service btif_av_sink_execute_service; struct btif_av_source_active_peer btif_av_source_active_peer; struct btif_av_source_execute_service btif_av_source_execute_service; -struct btif_av_src_disconnect_sink btif_av_src_disconnect_sink; struct btif_av_src_sink_coexist_enabled btif_av_src_sink_coexist_enabled; struct btif_av_stream_ready btif_av_stream_ready; struct btif_av_stream_start btif_av_stream_start; @@ -94,8 +92,6 @@ const RawAddress& btif_av_find_by_handle::return_value = RawAddress::kEmpty; uint16_t btif_av_get_audio_delay::return_value = 0; uint8_t btif_av_get_peer_sep::return_value = 0; const btav_sink_interface_t* btif_av_get_sink_interface::return_value = nullptr; -const btav_source_interface_t* btif_av_get_src_interface::return_value = - nullptr; bool btif_av_is_a2dp_offload_enabled::return_value = false; bool btif_av_is_a2dp_offload_running::return_value = false; bool btif_av_is_connected::return_value = false; @@ -149,10 +145,6 @@ const btav_sink_interface_t* btif_av_get_sink_interface(void) { inc_func_call_count(__func__); return test::mock::btif_av::btif_av_get_sink_interface(); } -const btav_source_interface_t* btif_av_get_src_interface(void) { - inc_func_call_count(__func__); - return test::mock::btif_av::btif_av_get_src_interface(); -} bool btif_av_is_a2dp_offload_enabled() { inc_func_call_count(__func__); return test::mock::btif_av::btif_av_is_a2dp_offload_enabled(); @@ -263,10 +255,6 @@ bt_status_t btif_av_source_execute_service(bool enable) { inc_func_call_count(__func__); return test::mock::btif_av::btif_av_source_execute_service(enable); } -void btif_av_src_disconnect_sink(const RawAddress& peer_address) { - inc_func_call_count(__func__); - test::mock::btif_av::btif_av_src_disconnect_sink(peer_address); -} bool btif_av_src_sink_coexist_enabled(void) { inc_func_call_count(__func__); return test::mock::btif_av::btif_av_src_sink_coexist_enabled(); diff --git a/system/test/mock/mock_btif_av.h b/system/test/mock/mock_btif_av.h index 53e51ed576c..e695f738445 100644 --- a/system/test/mock/mock_btif_av.h +++ b/system/test/mock/mock_btif_av.h @@ -133,17 +133,6 @@ struct btif_av_get_sink_interface { }; extern struct btif_av_get_sink_interface btif_av_get_sink_interface; -// Name: btif_av_get_src_interface -// Params: void -// Return: const btav_source_interface_t* -struct btif_av_get_src_interface { - static const btav_source_interface_t* return_value; - std::function body{ - [](void) { return return_value; }}; - const btav_source_interface_t* operator()(void) { return body(); }; -}; -extern struct btif_av_get_src_interface btif_av_get_src_interface; - // Name: btif_av_is_a2dp_offload_enabled // Params: // Return: bool @@ -453,16 +442,6 @@ struct btif_av_source_execute_service { }; extern struct btif_av_source_execute_service btif_av_source_execute_service; -// Name: btif_av_src_disconnect_sink -// Params: const RawAddress& peer_address -// Return: void -struct btif_av_src_disconnect_sink { - std::function body{ - [](const RawAddress& /* peer_address */) {}}; - void operator()(const RawAddress& peer_address) { body(peer_address); }; -}; -extern struct btif_av_src_disconnect_sink btif_av_src_disconnect_sink; - // Name: btif_av_src_sink_coexist_enabled // Params: void // Return: bool -- GitLab From 9852a94e75b474b275d86e4002f054be31021904 Mon Sep 17 00:00:00 2001 From: William Escande Date: Mon, 10 Jun 2024 17:48:36 -0700 Subject: [PATCH 0053/1446] ErrorProne: Enforce & fix NonApiType See https://errorprone.info/bugpattern/NonApiType Bug: 344658662 Test: m BluetoothInstrumentationTests Flag: Exempt Build and test only Change-Id: Ibf6b02e1ca0e8446013e388c03c305e25eac4d8d --- android/app/Android.bp | 1 + .../app/jni/com_android_bluetooth_gatt.cpp | 2 +- .../audio_util/MediaBrowserWrapper.java | 10 ++--- .../bip/BipImageProperties.java | 13 +++--- .../bluetooth/bass_client/BaseData.java | 25 +++++------ .../bluetooth/gatt/GattNativeInterface.java | 3 +- .../android/bluetooth/gatt/GattService.java | 2 +- .../le_scan/TransitionalScanHelper.java | 2 + .../map/BluetoothMapAccountLoader.java | 12 +++--- .../map/BluetoothMapAppObserver.java | 40 ++++++++---------- .../bluetooth/map/BluetoothMapContent.java | 17 ++++---- .../map/BluetoothMapContentObserver.java | 13 +++--- .../map/BluetoothMapMasInstance.java | 14 +++---- .../bluetooth/map/BluetoothMapService.java | 6 +-- .../bluetooth/map/BluetoothMapSettings.java | 6 +-- .../map/BluetoothMapSettingsAdapter.java | 20 ++++----- .../bluetooth/map/BluetoothMapSmsPdu.java | 12 +++--- .../bluetooth/map/BluetoothMapbMessage.java | 20 ++++----- .../map/BluetoothMapbMessageMime.java | 41 ++++++++++--------- .../map/BluetoothMapbMessageSms.java | 7 ++-- .../bluetooth/mapclient/MceStateMachine.java | 7 ++-- .../bluetooth/mapclient/obex/Bmessage.java | 9 ++-- .../bluetooth/mapclient/obex/EventReport.java | 3 +- .../mapclient/obex/FolderListing.java | 8 ++-- .../bluetooth/mapclient/obex/Message.java | 6 +-- .../mapclient/obex/MessagesListing.java | 12 +++--- .../obex/RequestGetFolderListing.java | 4 +- .../obex/RequestGetMessagesListing.java | 4 +- ...RequestGetMessagesListingForOwnNumber.java | 5 +-- .../bluetooth/opp/BluetoothOppManager.java | 14 +++---- .../bluetooth/opp/BluetoothOppUtility.java | 4 +- .../pbap/BluetoothPbapObexServer.java | 15 +++---- .../pbap/BluetoothPbapSimVcardManager.java | 10 ++--- .../bluetooth/pbap/BluetoothPbapUtils.java | 21 ++++------ .../pbap/BluetoothPbapVcardManager.java | 17 ++++---- .../pbapclient/BluetoothPbapRequest.java | 8 ++-- .../BluetoothPbapRequestPullPhoneBook.java | 4 +- .../pbapclient/BluetoothPbapVcardList.java | 5 ++- .../pbapclient/CallLogPullRequest.java | 6 +-- .../PbapClientConnectionHandler.java | 9 ++-- .../bluetooth/sap/SapRilReceiverHidl.java | 3 +- .../com/android/bluetooth/tbs/TbsGeneric.java | 4 +- .../telephony/BluetoothInCallService.java | 3 +- .../bluetooth/map/BluetoothMapSmsPduTest.java | 10 ++--- .../map/BluetoothMapbMessageSmsTest.java | 4 +- .../opp/BluetoothOppUtilityTest.java | 4 +- .../BluetoothPbapSimVcardManagerTest.java | 4 +- .../bluetooth/BluetoothManagerService.java | 9 ++-- 48 files changed, 239 insertions(+), 239 deletions(-) diff --git a/android/app/Android.bp b/android/app/Android.bp index 07a7cdd0ab7..b8b50fbacf0 100644 --- a/android/app/Android.bp +++ b/android/app/Android.bp @@ -329,6 +329,7 @@ android_app { "-Xep:InvalidBlockTag:ERROR", "-Xep:InvalidParam:ERROR", "-Xep:MockNotUsedInProduction:ERROR", + "-Xep:NonApiType:ERROR", "-Xep:NonCanonicalType:ERROR", "-Xep:ReturnAtTheEndOfVoidFunction:ERROR", "-Xep:UnusedMethod:ERROR", diff --git a/android/app/jni/com_android_bluetooth_gatt.cpp b/android/app/jni/com_android_bluetooth_gatt.cpp index e61e273c077..7e947378e7a 100644 --- a/android/app/jni/com_android_bluetooth_gatt.cpp +++ b/android/app/jni/com_android_bluetooth_gatt.cpp @@ -2882,7 +2882,7 @@ static int register_com_android_bluetooth_gatt_(JNIEnv* env) { {"onClientCongestion", "(IZ)V", &method_onClientCongestion}, {"getSampleGattDbElement", "()Lcom/android/bluetooth/gatt/GattDbElement;", &method_getSampleGattDbElement}, - {"onGetGattDb", "(ILjava/util/ArrayList;)V", &method_onGetGattDb}, + {"onGetGattDb", "(ILjava/util/List;)V", &method_onGetGattDb}, {"onClientPhyRead", "(ILjava/lang/String;III)V", &method_onClientPhyRead}, {"onClientPhyUpdate", "(IIII)V", &method_onClientPhyUpdate}, {"onClientConnUpdate", "(IIIII)V", &method_onClientConnUpdate}, diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaBrowserWrapper.java b/android/app/src/com/android/bluetooth/audio_util/MediaBrowserWrapper.java index c330cbaf37b..7a8e0dc8180 100644 --- a/android/app/src/com/android/bluetooth/audio_util/MediaBrowserWrapper.java +++ b/android/app/src/com/android/bluetooth/audio_util/MediaBrowserWrapper.java @@ -31,6 +31,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Handles API calls to a MediaBrowser. @@ -41,7 +42,6 @@ import java.util.List; * callback when it gets the answer from MediaBrowser. */ class MediaBrowserWrapper { - private static final String TAG = MediaBrowserWrapper.class.getSimpleName(); /** @@ -86,8 +86,7 @@ class MediaBrowserWrapper { // GetFolderItems also works with a callback, so we need to store all requests made before we // got the results and prevent new subscriptions. - private final HashMap> mSubscribedIds = - new HashMap<>(); + private final Map> mSubscribedIds = new HashMap<>(); private final Runnable mDisconnectRunnable = () -> _disconnect(); @@ -328,7 +327,7 @@ class MediaBrowserWrapper { mRunHandler.postDelayed(mTimeoutRunnable, BROWSER_DISCONNECT_TIMEOUT.toMillis()); } - private void executeCallbacks(String parentId, ArrayList browsableContent) { + private void executeCallbacks(String parentId, List browsableContent) { if (mCallbacksExecuted) { return; } @@ -353,8 +352,7 @@ class MediaBrowserWrapper { @Override public void onChildrenLoaded(String parentId, List children) { - - ArrayList browsableContent = new ArrayList<>(); + List browsableContent = new ArrayList<>(); for (MediaItem item : children) { if (item.isBrowsable()) { diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java index e5b1e5b8838..44a56579074 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java @@ -29,6 +29,7 @@ import java.io.InputStream; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.List; import java.util.Objects; /** @@ -142,10 +143,10 @@ public class BipImageProperties { private boolean mHasThumbnailFormat = false; /** The various sets of available formats. */ - private ArrayList mNativeFormats; + private List mNativeFormats; - private ArrayList mVariantFormats; - private ArrayList mAttachments; + private List mVariantFormats; + private List mAttachments; private BipImageProperties() { mVersion = sVersion; @@ -226,15 +227,15 @@ public class BipImageProperties { return mFriendlyName; } - public ArrayList getNativeFormats() { + public List getNativeFormats() { return mNativeFormats; } - public ArrayList getVariantFormats() { + public List getVariantFormats() { return mVariantFormats; } - public ArrayList getAttachments() { + public List getAttachments() { return mAttachments; } diff --git a/android/app/src/com/android/bluetooth/bass_client/BaseData.java b/android/app/src/com/android/bluetooth/bass_client/BaseData.java index bd5a4dba5d3..4bc0dc76494 100644 --- a/android/app/src/com/android/bluetooth/bass_client/BaseData.java +++ b/android/app/src/com/android/bluetooth/bass_client/BaseData.java @@ -25,6 +25,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.MissingResourceException; @@ -57,8 +58,8 @@ class BaseData { private static final int CODEC_AUDIO_FRAME_DURATION_10MS = 0x01; private final BaseInformation mLevelOne; - private final ArrayList mLevelTwo; - private final ArrayList mLevelThree; + private final List mLevelTwo; + private final List mLevelThree; private int mNumBISIndices = 0; @@ -185,8 +186,8 @@ class BaseData { BaseData( BaseInformation levelOne, - ArrayList levelTwo, - ArrayList levelThree, + List levelTwo, + List levelThree, int numOfBISIndices) { mLevelOne = levelOne; mLevelTwo = levelTwo; @@ -200,8 +201,8 @@ class BaseData { throw new IllegalArgumentException("Basedata: serviceData is null"); } BaseInformation levelOne = new BaseInformation(); - ArrayList levelTwo = new ArrayList(); - ArrayList levelThree = new ArrayList(); + List levelTwo = new ArrayList<>(); + List levelThree = new ArrayList<>(); int numOfBISIndices = 0; log("BASE input" + Arrays.toString(serviceData)); @@ -291,7 +292,7 @@ class BaseData { } static void consolidateBaseofLevelTwo( - ArrayList levelTwo, ArrayList levelThree) { + List levelTwo, List levelThree) { int startIdx = 0; int children = 0; for (int i = 0; i < levelTwo.size(); i++) { @@ -350,8 +351,8 @@ class BaseData { } static void consolidateBaseofLevelThree( - ArrayList levelTwo, - ArrayList levelThree, + List levelTwo, + List levelThree, int parentSubgroup, int startIdx, int numNodes) { @@ -387,11 +388,11 @@ class BaseData { return mLevelOne; } - public ArrayList getLevelTwo() { + public List getLevelTwo() { return mLevelTwo; } - public ArrayList getLevelThree() { + public List getLevelThree() { return mLevelThree; } @@ -403,7 +404,7 @@ class BaseData { return ret; } - public ArrayList getBISIndexInfos() { + public List getBISIndexInfos() { return mLevelThree; } diff --git a/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java b/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java index d6b0a4dd4a8..79f3638f6e8 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java +++ b/android/app/src/com/android/bluetooth/gatt/GattNativeInterface.java @@ -21,7 +21,6 @@ import android.os.RemoteException; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import java.util.ArrayList; import java.util.List; /** GATT Profile Native Interface to/from JNI. */ @@ -133,7 +132,7 @@ public class GattNativeInterface { return getGattService().getSampleGattDbElement(); } - void onGetGattDb(int connId, ArrayList db) throws RemoteException { + void onGetGattDb(int connId, List db) throws RemoteException { getGattService().onGetGattDb(connId, db); } diff --git a/android/app/src/com/android/bluetooth/gatt/GattService.java b/android/app/src/com/android/bluetooth/gatt/GattService.java index 495fbcdeaac..bec2b6f3cc4 100644 --- a/android/app/src/com/android/bluetooth/gatt/GattService.java +++ b/android/app/src/com/android/bluetooth/gatt/GattService.java @@ -1555,7 +1555,7 @@ public class GattService extends ProfileService { return new GattDbElement(); } - void onGetGattDb(int connId, ArrayList db) throws RemoteException { + void onGetGattDb(int connId, List db) throws RemoteException { String address = mClientMap.addressByConnId(connId); Log.d(TAG, "onGetGattDb() - address=" + address); 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 ec7179e0207..663e57dbad8 100644 --- a/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java +++ b/android/app/src/com/android/bluetooth/le_scan/TransitionalScanHelper.java @@ -493,6 +493,7 @@ public class TransitionalScanHelper { } } + @SuppressWarnings("NonApiType") private void sendResultsByPendingIntent( PendingIntentInfo pii, ArrayList results, int callbackType) throws PendingIntent.CanceledException { @@ -750,6 +751,7 @@ public class TransitionalScanHelper { mScanManager.callbackDone(scannerId, status); } + @SuppressWarnings("NonApiType") private void sendBatchScanResults( ContextMap.App app, ScanClient client, diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapAccountLoader.java b/android/app/src/com/android/bluetooth/map/BluetoothMapAccountLoader.java index cebff3cfcdc..f985c0dfbd6 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapAccountLoader.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapAccountLoader.java @@ -38,6 +38,7 @@ import com.android.bluetooth.mapapi.BluetoothMapContract; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Objects; // Next tag value for ContentProfileErrorReportUtils.report(): 1 @@ -63,11 +64,10 @@ public class BluetoothMapAccountLoader { * @return LinkedHashMap with the packages as keys(BluetoothMapAccountItem) and values as * ArrayLists of BluetoothMapAccountItems. */ - public LinkedHashMap> parsePackages( + public Map> parsePackages( boolean includeIcon) { - LinkedHashMap> groups = - new LinkedHashMap>(); + Map> groups = new LinkedHashMap<>(); Intent[] searchIntents = new Intent[2]; // Array searchIntents = new Array (); searchIntents[0] = new Intent(BluetoothMapContract.PROVIDER_INTERFACE_EMAIL); @@ -103,7 +103,7 @@ public class BluetoothMapAccountLoader { == 0) { BluetoothMapAccountItem app = createAppItem(rInfo, includeIcon, msgType); if (app != null) { - ArrayList accounts = parseAccounts(app); + List accounts = parseAccounts(app); // we do not want to list apps without accounts if (accounts.size() > 0) { // we need to make sure that the "select all" checkbox @@ -166,10 +166,10 @@ public class BluetoothMapAccountLoader { * @param app The parent app object * @return An ArrayList of BluetoothMapAccountItems containing all the accounts from the app */ - public ArrayList parseAccounts(BluetoothMapAccountItem app) { + public List parseAccounts(BluetoothMapAccountItem app) { Cursor c = null; Log.d(TAG, "Finding accounts for app " + app.getPackageName()); - ArrayList children = new ArrayList(); + List children = new ArrayList<>(); // Get the list of accounts from the email apps content resolver (if possible) mResolver = mContext.getContentResolver(); try { diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapAppObserver.java b/android/app/src/com/android/bluetooth/map/BluetoothMapAppObserver.java index dfc2e5b1634..8169cb9305a 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapAppObserver.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapAppObserver.java @@ -34,6 +34,7 @@ import com.android.bluetooth.mapapi.BluetoothMapContract; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Objects; /** Class to construct content observers for email applications on the system. */ @@ -43,9 +44,8 @@ public class BluetoothMapAppObserver { private static final String TAG = "BluetoothMapAppObserver"; /* */ - private LinkedHashMap> mFullList; - private LinkedHashMap mObserverMap = - new LinkedHashMap(); + private Map> mFullList; + private Map mObserverMap = new LinkedHashMap<>(); private ContentResolver mResolver; private Context mContext; private BroadcastReceiver mReceiver; @@ -85,17 +85,16 @@ public class BluetoothMapAppObserver { // String packageName = packageNameWithProvider.replaceFirst("\\.[^\\.]+$", ""); BluetoothMapAccountItem app = getApp(packageNameWithProvider); if (app != null) { - ArrayList newAccountList = mLoader.parseAccounts(app); - ArrayList oldAccountList = mFullList.get(app); - ArrayList addedAccountList = - (ArrayList) newAccountList.clone(); + List newAccountList = mLoader.parseAccounts(app); + List oldAccountList = mFullList.get(app); + List addedAccountList = new ArrayList<>(newAccountList); // Same as oldAccountList.clone - ArrayList removedAccountList = mFullList.get(app); + List removedAccountList = mFullList.get(app); if (oldAccountList == null) { - oldAccountList = new ArrayList(); + oldAccountList = new ArrayList<>(); } if (removedAccountList == null) { - removedAccountList = new ArrayList(); + removedAccountList = new ArrayList<>(); } mFullList.put(app, newAccountList); @@ -302,9 +301,7 @@ public class BluetoothMapAppObserver { if (app != null) { registerObserver(app); // Add all accounts to mFullList - ArrayList newAccountList = - mLoader.parseAccounts(app); - mFullList.put(app, newAccountList); + mFullList.put(app, mLoader.parseAccounts(app)); } } @@ -356,14 +353,14 @@ public class BluetoothMapAppObserver { /** * Method to get a list of the accounts (across all apps) that are set to be shared through MAP. * - * @return Arraylist containing all enabled accounts + * @return List containing all enabled accounts */ - public ArrayList getEnabledAccountItems() { + public List getEnabledAccountItems() { Log.d(TAG, "getEnabledAccountItems()\n"); - ArrayList list = new ArrayList(); + List list = new ArrayList<>(); for (BluetoothMapAccountItem app : mFullList.keySet()) { if (app != null) { - ArrayList accountList = mFullList.get(app); + List accountList = mFullList.get(app); if (accountList != null) { for (BluetoothMapAccountItem acc : accountList) { if (acc.mIsChecked) { @@ -394,14 +391,13 @@ public class BluetoothMapAppObserver { /** * Method to get a list of the accounts (across all apps). * - * @return Arraylist containing all accounts + * @return List containing all accounts */ - public ArrayList getAllAccountItems() { + public List getAllAccountItems() { Log.d(TAG, "getAllAccountItems()\n"); - ArrayList list = new ArrayList(); + List list = new ArrayList<>(); for (BluetoothMapAccountItem app : mFullList.keySet()) { - ArrayList accountList = mFullList.get(app); - list.addAll(accountList); + list.addAll(mFullList.get(app)); } return list; } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java b/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java index d77a7b22ab3..a04e86108ae 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java @@ -62,6 +62,7 @@ import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.HashMap; import java.util.List; +import java.util.Map; // Next tag value for ContentProfileErrorReportUtils.report(): 15 public class BluetoothMapContent { @@ -617,7 +618,7 @@ public class BluetoothMapContent { + " Changing size to 1"); size = 1; } - // TODO: Add handling of attachemnt mime types + // TODO: Add handling of attachment mime types } } else if (fi.mMsgType == FilterInfo.TYPE_EMAIL) { int attachment = c.getInt(fi.mMessageColAttachment); @@ -2948,7 +2949,7 @@ public class BluetoothMapContent { /** * Refreshes the entire list of SMS/MMS conversation version counters. Use it to generate a new - * ConvoListVersinoCounter in mSmsMmsConvoListVersion + * ConvoListVersionCounter in mSmsMmsConvoListVersion * * @return true if a list change has been detected */ @@ -2965,7 +2966,7 @@ public class BluetoothMapContent { cursor.moveToPosition(-1); synchronized (getSmsMmsConvoList()) { int size = Math.max(getSmsMmsConvoList().size(), cursor.getCount()); - HashMap newList = + Map newList = new HashMap(size); while (cursor.moveToNext()) { // TODO: Extract to function, that can be called at listing, which returns @@ -3069,7 +3070,7 @@ public class BluetoothMapContent { synchronized (getImEmailConvoList()) { int size = Math.max(getImEmailConvoList().size(), imEmailCursor.getCount()); boolean convoChanged = false; - HashMap newList = + Map newList = new HashMap(size); while (isValid) { long id = imEmailCursor.getLong(fi.mConvoColConvoId); @@ -4402,19 +4403,19 @@ public class BluetoothMapContent { return this.mRemoteFeatureMask; } - HashMap getSmsMmsConvoList() { + Map getSmsMmsConvoList() { return mMasInstance.getSmsMmsConvoList(); } - void setSmsMmsConvoList(HashMap smsMmsConvoList) { + void setSmsMmsConvoList(Map smsMmsConvoList) { mMasInstance.setSmsMmsConvoList(smsMmsConvoList); } - HashMap getImEmailConvoList() { + Map getImEmailConvoList() { return mMasInstance.getImEmailConvoList(); } - void setImEmailConvoList(HashMap imEmailConvoList) { + void setImEmailConvoList(Map imEmailConvoList) { mMasInstance.setImEmailConvoList(imEmailConvoList); } } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java index a8b0493eaad..5c47fd566a2 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java @@ -82,6 +82,7 @@ import java.util.Calendar; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -3073,7 +3074,7 @@ public class BluetoothMapContentObserver { String emailBaseUri) throws IllegalArgumentException, RemoteException, IOException { Log.d(TAG, "pushMessage"); - ArrayList recipientList = msg.getRecipients(); + List recipientList = msg.getRecipients(); int transparent = (ap.getTransparent() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) ? 0 @@ -3204,7 +3205,7 @@ public class BluetoothMapContentObserver { } else if (msg.getType().equals(TYPE.MMS) && (recipientList.size() > 1)) { // Group MMS String folder = folderElement.getName(); - ArrayList telNums = new ArrayList(); + List telNums = new ArrayList(); for (BluetoothMapbMessage.VCard recipient : recipientList) { // Only send the message to the top level recipient if (recipient.getEnvLevel() == 0) { @@ -3236,7 +3237,7 @@ public class BluetoothMapContentObserver { && (((BluetoothMapbMessageMime) msg).getTextOnly())) { msgBody = ((BluetoothMapbMessageMime) msg).getMessageAsText(); SmsManager smsMng = SmsManager.getDefault(); - ArrayList parts = smsMng.divideMessage(msgBody); + List parts = smsMng.divideMessage(msgBody); int smsParts = parts.size(); if (smsParts <= CONVERT_MMS_TO_SMS_PART_COUNT) { Log.d( @@ -3734,15 +3735,15 @@ public class BluetoothMapContentObserver { public void sendMessage(PushMsgInfo msgInfo, String msgBody) { SmsManager smsMng = SmsManager.getDefault(); - ArrayList parts = smsMng.divideMessage(msgBody); + List parts = smsMng.divideMessage(msgBody); msgInfo.parts = parts.size(); // We add a time stamp to differentiate delivery reports from each other for resent messages msgInfo.timestamp = Calendar.getInstance().getTimeInMillis(); msgInfo.partsDelivered = 0; msgInfo.partsSent = 0; - ArrayList deliveryIntents = new ArrayList(msgInfo.parts); - ArrayList sentIntents = new ArrayList(msgInfo.parts); + List deliveryIntents = new ArrayList(msgInfo.parts); + List sentIntents = new ArrayList(msgInfo.parts); /* We handle the SENT intent in the MAP service, as this object * is destroyed at disconnect, hence if a disconnect occur while sending diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java b/android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java index bf8674a7b42..5300907db90 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapMasInstance.java @@ -102,11 +102,9 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { private Map mContactList; - private HashMap mSmsMmsConvoList = - new HashMap(); + private Map mSmsMmsConvoList = new HashMap<>(); - private HashMap mImEmailConvoList = - new HashMap(); + private Map mImEmailConvoList = new HashMap<>(); private int mRemoteFeatureMask = BluetoothMapUtils.MAP_FEATURE_DEFAULT_BITMASK; private static int sFeatureMask = SDP_MAP_MAS_FEATURES_1_4; @@ -225,19 +223,19 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { mContactList = contactList; } - HashMap getSmsMmsConvoList() { + Map getSmsMmsConvoList() { return mSmsMmsConvoList; } - void setSmsMmsConvoList(HashMap smsMmsConvoList) { + void setSmsMmsConvoList(Map smsMmsConvoList) { mSmsMmsConvoList = smsMmsConvoList; } - HashMap getImEmailConvoList() { + Map getImEmailConvoList() { return mImEmailConvoList; } - void setImEmailConvoList(HashMap imEmailConvoList) { + void setImEmailConvoList(Map imEmailConvoList) { mImEmailConvoList = imEmailConvoList; } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapService.java b/android/app/src/com/android/bluetooth/map/BluetoothMapService.java index fc2c241dec3..5cca98e16b3 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapService.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapService.java @@ -132,7 +132,7 @@ public class BluetoothMapService extends ProfileService { // The remote connected device - protect access private static BluetoothDevice sRemoteDevice = null; - private ArrayList mEnabledAccounts = null; + private List mEnabledAccounts = null; private static String sRemoteDeviceName = null; private int mState = BluetoothMap.STATE_DISCONNECTED; @@ -789,8 +789,8 @@ public class BluetoothMapService extends ProfileService { return; } - ArrayList newAccountList = mAppObserver.getEnabledAccountItems(); - ArrayList newAccounts = new ArrayList<>(); + List newAccountList = mAppObserver.getEnabledAccountItems(); + List newAccounts = new ArrayList<>(); for (BluetoothMapAccountItem account : newAccountList) { if (!mEnabledAccounts.remove(account)) { diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapSettings.java b/android/app/src/com/android/bluetooth/map/BluetoothMapSettings.java index e8509cc564b..74ccd0f8a4b 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapSettings.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapSettings.java @@ -23,14 +23,14 @@ import android.widget.ExpandableListView; import com.android.bluetooth.R; -import java.util.ArrayList; -import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; public class BluetoothMapSettings extends Activity { private static final String TAG = "BluetoothMapSettings"; BluetoothMapAccountLoader mLoader = new BluetoothMapAccountLoader(this); - LinkedHashMap> mGroups; + Map> mGroups; @Override protected void onCreate(Bundle savedInstanceState) { diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapSettingsAdapter.java b/android/app/src/com/android/bluetooth/map/BluetoothMapSettingsAdapter.java index 72ca9de0491..3416b797027 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapSettingsAdapter.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapSettingsAdapter.java @@ -38,7 +38,7 @@ import com.android.bluetooth.R; import com.android.bluetooth.mapapi.BluetoothMapContract; import java.util.ArrayList; -import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { @@ -47,10 +47,10 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { private boolean mCheckAll = true; public LayoutInflater mInflater; public Activity mActivity; - /*needed to prevent random checkbox toggles due to item reuse */ ArrayList - mPositionArray; - private LinkedHashMap> mProupList; - private ArrayList mMainGroup; + /* needed to prevent random checkbox toggles due to item reuse */ + List mPositionArray; + private Map> mProupList; + private List mMainGroup; private int[] mGroupStatus; /* number of accounts possible to share */ private int mSlotsLeft = 10; @@ -58,7 +58,7 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { public BluetoothMapSettingsAdapter( Activity act, ExpandableListView listView, - LinkedHashMap> groupsList, + Map> groupsList, int enabledAccountsCounts) { mActivity = act; this.mProupList = groupsList; @@ -78,7 +78,7 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { } }); mMainGroup = new ArrayList(); - for (Map.Entry> mapEntry : + for (Map.Entry> mapEntry : mProupList.entrySet()) { mMainGroup.add(mapEntry.getKey()); } @@ -90,7 +90,7 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { return mProupList.get(item).get(childPosition); } - private ArrayList getChild(BluetoothMapAccountItem group) { + private List getChild(BluetoothMapAccountItem group) { return mProupList.get(group); } @@ -130,7 +130,7 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { child.mIsChecked; // needed to prevent updates on UI redraw child.mIsChecked = isChecked; if (isChecked) { - ArrayList childList = getChild(parentGroup); + List childList = getChild(parentGroup); int childIndex = childList.indexOf(child); boolean isAllChildClicked = true; if (mSlotsLeft - childList.size() >= 0) { @@ -253,7 +253,7 @@ public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (mCheckAll) { - ArrayList childItem = getChild(groupItem); + List childItem = getChild(groupItem); for (BluetoothMapAccountItem children : childItem) { boolean oldIsChecked = children.mIsChecked; if (mSlotsLeft > 0) { diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java index afe6f646ee2..85b09515582 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java @@ -37,6 +37,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; +import java.util.List; import java.util.Random; // Next tag value for ContentProfileErrorReportUtils.report(): 10 @@ -522,8 +523,7 @@ public class BluetoothMapSmsPdu { return sConcatenatedRef; } - public static ArrayList getSubmitPdus( - Context context, String messageText, String address) { + public static List getSubmitPdus(Context context, String messageText, String address) { /* Use the generic GSM/CDMA SMS Message functionality within Android to generate the * SMS PDU's as once generated to send the SMS message. */ @@ -540,8 +540,8 @@ public class BluetoothMapSmsPdu { int languageShiftTable; int refNumber = getNextConcatenatedRef() & 0x00FF; SmsManager smsMng = SmsManager.getDefault(); - ArrayList smsFragments = smsMng.divideMessage(messageText); - ArrayList pdus = new ArrayList(msgCount); + List smsFragments = smsMng.divideMessage(messageText); + List pdus = new ArrayList<>(msgCount); byte[] data; // Default to GSM, as this code should not be used, if we neither have CDMA not GSM. @@ -592,9 +592,9 @@ public class BluetoothMapSmsPdu { * @param address The originator address. * @param date The delivery time stamp. */ - public static ArrayList getDeliverPdus( + public static List getDeliverPdus( Context context, String messageText, String address, long date) { - ArrayList deliverPdus = getSubmitPdus(context, messageText, address); + List deliverPdus = getSubmitPdus(context, messageText, address); /* * For CDMA the only difference between deliver and submit pdus are the messageType, diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java index b4fe62c0002..6d8cb70665b 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.List; // Next tag value for ContentProfileErrorReportUtils.report(): 10 public abstract class BluetoothMapbMessage { @@ -53,8 +54,8 @@ public abstract class BluetoothMapbMessage { private int mBMsgLength = INVALID_VALUE; - private ArrayList mOriginator = null; - private ArrayList mRecipient = null; + private List mOriginator = null; + private List mRecipient = null; public static class VCard { /* VCARD attributes */ @@ -250,10 +251,10 @@ public abstract class BluetoothMapbMessage { static VCard parseVcard(BMsgReader reader, int envLevel) { String formattedName = null; String name = null; - ArrayList phoneNumbers = null; - ArrayList emailAddresses = null; - ArrayList btUids = null; - ArrayList btUcis = null; + List phoneNumbers = null; + List emailAddresses = null; + List btUids = null; + List btUcis = null; String[] parts; String line = reader.getLineEnforce(); @@ -791,7 +792,7 @@ public abstract class BluetoothMapbMessage { this.mEncoding = encoding; } - public ArrayList getOriginators() { + public List getOriginators() { return mOriginator; } @@ -841,7 +842,7 @@ public abstract class BluetoothMapbMessage { mOriginator.add(new VCard(name, phoneNumbers, emailAddresses)); } - public ArrayList getRecipients() { + public List getRecipients() { return mRecipient; } @@ -935,8 +936,7 @@ public abstract class BluetoothMapbMessage { return out; } - public byte[] encodeGeneric(ArrayList bodyFragments) - throws UnsupportedEncodingException { + public byte[] encodeGeneric(List bodyFragments) throws UnsupportedEncodingException { StringBuilder sb = new StringBuilder(256); byte[] msgStart, msgEnd; sb.append("BEGIN:BMSG").append("\r\n"); diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java index f490053d2d9..47bfa2deaa0 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java @@ -31,6 +31,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.List; import java.util.Locale; import java.util.UUID; @@ -169,12 +170,12 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { private long mDate = INVALID_VALUE; private String mSubject = null; - private ArrayList mFrom = null; // Shall not be empty - private ArrayList mSender = null; // Shall not be empty - private ArrayList mTo = null; // Shall not be empty - private ArrayList mCc = null; // Can be empty - private ArrayList mBcc = null; // Can be empty - private ArrayList mReplyTo = null; // Can be empty + private List mFrom = null; // Shall not be empty + private List mSender = null; // Shall not be empty + private List mTo = null; // Shall not be empty + private List mCc = null; // Can be empty + private List mBcc = null; // Can be empty + private List mReplyTo = null; // Can be empty private String mMessageId = null; private ArrayList mParts = null; private String mContentType = null; @@ -194,7 +195,7 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { /** * @return the parts */ - public ArrayList getMimeParts() { + public List getMimeParts() { return mParts; } @@ -244,11 +245,11 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { this.mSubject = subject; } - public ArrayList getFrom() { + public List getFrom() { return mFrom; } - public void setFrom(ArrayList from) { + public void setFrom(List from) { this.mFrom = from; } @@ -259,11 +260,11 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { this.mFrom.add(new Rfc822Token(name, address, null)); } - public ArrayList getSender() { + public List getSender() { return mSender; } - public void setSender(ArrayList sender) { + public void setSender(List sender) { this.mSender = sender; } @@ -274,11 +275,11 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { this.mSender.add(new Rfc822Token(name, address, null)); } - public ArrayList getTo() { + public List getTo() { return mTo; } - public void setTo(ArrayList to) { + public void setTo(List to) { this.mTo = to; } @@ -289,11 +290,11 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { this.mTo.add(new Rfc822Token(name, address, null)); } - public ArrayList getCc() { + public List getCc() { return mCc; } - public void setCc(ArrayList cc) { + public void setCc(List cc) { this.mCc = cc; } @@ -304,11 +305,11 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { this.mCc.add(new Rfc822Token(name, address, null)); } - public ArrayList getBcc() { + public List getBcc() { return mBcc; } - public void setBcc(ArrayList bcc) { + public void setBcc(List bcc) { this.mBcc = bcc; } @@ -319,11 +320,11 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { this.mBcc.add(new Rfc822Token(name, address, null)); } - public ArrayList getReplyTo() { + public List getReplyTo() { return mReplyTo; } - public void setReplyTo(ArrayList replyTo) { + public void setReplyTo(List replyTo) { this.mReplyTo = replyTo; } @@ -397,7 +398,7 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { * @param addresses the reformatted address substrings to encode. */ public void encodeHeaderAddresses( - StringBuilder sb, String headerName, ArrayList addresses) { + StringBuilder sb, String headerName, List addresses) { /* TODO: Do we need to encode the addresses if they contain illegal characters? * This depends of the outcome of errata 4176. The current spec. states to use UTF-8 * where possible, but the RFCs states to use US-ASCII for the headers - hence encoding diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java index a04245f619c..48add7a2e78 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java @@ -22,13 +22,14 @@ import com.android.bluetooth.map.BluetoothMapUtils.TYPE; import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.List; public class BluetoothMapbMessageSms extends BluetoothMapbMessage { - private ArrayList mSmsBodyPdus = null; + private List mSmsBodyPdus = null; private String mSmsBody = null; - public void setSmsBodyPdus(ArrayList smsBodyPdus) { + public void setSmsBodyPdus(List smsBodyPdus) { this.mSmsBodyPdus = smsBodyPdus; this.mCharset = null; if (smsBodyPdus.size() > 0) { @@ -76,7 +77,7 @@ public class BluetoothMapbMessageSms extends BluetoothMapbMessage { @Override public byte[] encode() throws UnsupportedEncodingException { - ArrayList bodyFragments = new ArrayList(); + List bodyFragments = new ArrayList<>(); /* Store the messages in an ArrayList to be able to handle the different message types in a generic way. diff --git a/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java b/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java index c53dd395b80..07ce3ee71d2 100644 --- a/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java +++ b/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java @@ -64,7 +64,6 @@ import com.android.vcard.VCardEntry; import com.android.vcard.VCardProperty; import java.time.Instant; -import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.HashSet; @@ -918,7 +917,7 @@ class MceStateMachine extends StateMachine { : "null list") : "null request")); - ArrayList messageListing = request.getList(); + List messageListing = request.getList(); if (messageListing != null) { // Message listings by spec arrive ordered newest first but we wish to broadcast as // oldest first. Iterate in reverse order so we initiate requests oldest first. @@ -1117,7 +1116,7 @@ class MceStateMachine extends StateMachine { mmsBmessage.parseMsgPart(message.getBodyContent()); intent.putExtra( android.content.Intent.EXTRA_TEXT, mmsBmessage.getMessageAsText()); - ArrayList recipients = message.getRecipients(); + List recipients = message.getRecipients(); if (recipients != null && !recipients.isEmpty()) { intent.putExtra( android.content.Intent.EXTRA_CC, getRecipientsUri(recipients)); @@ -1154,7 +1153,7 @@ class MceStateMachine extends StateMachine { * Retrieves the URIs of all the participants of a group conversation, besides the sender of * the message. */ - private String[] getRecipientsUri(ArrayList recipients) { + private String[] getRecipientsUri(List recipients) { Set uris = new HashSet<>(); for (VCardEntry recipient : recipients) { diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/Bmessage.java b/android/app/src/com/android/bluetooth/mapclient/obex/Bmessage.java index 044bbdf70ef..797d93b8efb 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/Bmessage.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/Bmessage.java @@ -22,6 +22,7 @@ import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; +import java.util.List; /** * Object representation of message in bMessage format @@ -42,8 +43,8 @@ public class Bmessage { String mMessage; - ArrayList mOriginators; - ArrayList mRecipients; + List mOriginators; + List mRecipients; /** Constructs empty message object */ public Bmessage() { @@ -59,7 +60,7 @@ public class Bmessage { } } - public ArrayList getOriginators() { + public List getOriginators() { return mOriginators; } @@ -68,7 +69,7 @@ public class Bmessage { return this; } - public ArrayList getRecipients() { + public List getRecipients() { return mRecipients; } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/EventReport.java b/android/app/src/com/android/bluetooth/mapclient/obex/EventReport.java index c883f5c6f3d..f11c5c845e1 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/EventReport.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/EventReport.java @@ -31,6 +31,7 @@ import java.io.DataInputStream; import java.io.IOException; import java.math.BigInteger; import java.util.HashMap; +import java.util.Map; /** * Object representation of event report received by MNS @@ -47,7 +48,7 @@ public class EventReport { private final Bmessage.Type mMsgType; @VisibleForTesting - EventReport(HashMap attrs) throws IllegalArgumentException { + EventReport(Map attrs) throws IllegalArgumentException { mType = parseType(attrs.get("type")); if (mType != Type.MEMORY_FULL && mType != Type.MEMORY_AVAILABLE) { diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/FolderListing.java b/android/app/src/com/android/bluetooth/mapclient/obex/FolderListing.java index cd1ecc4c052..74a3ed2152e 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/FolderListing.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/FolderListing.java @@ -25,21 +25,19 @@ import org.xmlpull.v1.XmlPullParserFactory; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.List; class FolderListing { private static final String TAG = "FolderListing"; - private final ArrayList mFolders; + private final List mFolders = new ArrayList<>(); FolderListing(InputStream in) { - mFolders = new ArrayList(); - parse(in); } public void parse(InputStream in) { - try { XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser(); xpp.setInput(in, "utf-8"); @@ -64,7 +62,7 @@ class FolderListing { } } - public ArrayList getList() { + public List getList() { return mFolders; } } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/Message.java b/android/app/src/com/android/bluetooth/mapclient/obex/Message.java index ec8403a1b4d..89f40cc7d23 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/Message.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/Message.java @@ -21,7 +21,7 @@ import org.json.JSONObject; import java.math.BigInteger; import java.util.Date; -import java.util.HashMap; +import java.util.Map; /** * Object representation of message received in messages listing @@ -64,7 +64,7 @@ public class Message { private final boolean mProtected; - Message(HashMap attrs) throws IllegalArgumentException { + Message(Map attrs) throws IllegalArgumentException { int size; try { @@ -82,7 +82,7 @@ public class Message { mSubject = attrs.get("subject"); String dateTime = attrs.get("datetime"); - // Handle possible NPE when not able to retreive datetime attribute + // Handle possible NPE when not able to retrieve datetime attribute if (dateTime != null) { mDateTime = (new ObexTime(dateTime)).getTime(); } else { diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/MessagesListing.java b/android/app/src/com/android/bluetooth/mapclient/obex/MessagesListing.java index d473819ec0c..799384a57b2 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/MessagesListing.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/MessagesListing.java @@ -26,21 +26,19 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; class MessagesListing { - private static final String TAG = "MessagesListing"; - private final ArrayList mMessages; + private final List mMessages = new ArrayList<>(); MessagesListing(InputStream in) { - mMessages = new ArrayList(); - parse(in); } public void parse(InputStream in) { - try { XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser(); xpp.setInput(in, "utf-8"); @@ -51,7 +49,7 @@ class MessagesListing { case XmlPullParser.START_TAG: if (xpp.getName().equals("msg")) { - HashMap attrs = new HashMap(); + Map attrs = new HashMap<>(); for (int i = 0; i < xpp.getAttributeCount(); i++) { attrs.put(xpp.getAttributeName(i), xpp.getAttributeValue(i)); @@ -78,7 +76,7 @@ class MessagesListing { } } - public ArrayList getList() { + public List getList() { return mMessages; } } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetFolderListing.java b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetFolderListing.java index bad6a91524a..9b66bd3dcf0 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetFolderListing.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetFolderListing.java @@ -22,7 +22,7 @@ import com.android.obex.HeaderSet; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; +import java.util.List; /* Get a listing of subdirectories. */ final class RequestGetFolderListing extends Request { @@ -61,7 +61,7 @@ final class RequestGetFolderListing extends Request { mResponse = new FolderListing(stream); } - public ArrayList getList() { + public List getList() { if (mResponse == null) { return null; } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListing.java b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListing.java index c3ff77c7144..80f4176e477 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListing.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListing.java @@ -22,8 +22,8 @@ import com.android.obex.HeaderSet; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; import java.util.Date; +import java.util.List; /* Get a listing of messages in directory. */ class RequestGetMessagesListing extends Request { @@ -135,7 +135,7 @@ class RequestGetMessagesListing extends Request { } } - public ArrayList getList() { + public List getList() { if (mResponse == null) { return null; } diff --git a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListingForOwnNumber.java b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListingForOwnNumber.java index 852ecfee0df..a904b3bf2bf 100644 --- a/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListingForOwnNumber.java +++ b/android/app/src/com/android/bluetooth/mapclient/obex/RequestGetMessagesListingForOwnNumber.java @@ -150,7 +150,7 @@ class RequestGetMessagesListingForOwnNumber extends Request { return; } - ArrayList messageListing = response.getList(); + List messageListing = response.getList(); if (messageListing == null || messageListing.isEmpty()) { // No more messages in this folder; move on to the next folder; logD("readResponse: no messages, moving to next folder"); @@ -170,8 +170,7 @@ class RequestGetMessagesListingForOwnNumber extends Request { mMessageListingWindow.getStartOffset(), mMessageListingWindow.getMaxCount())); String number = null; - for (int i = 0; i < messageListing.size(); i++) { - Message msg = messageListing.get(i); + for (Message msg : messageListing) { if (MceStateMachine.FOLDER_INBOX.equals(folderName)) { number = PhoneNumberUtils.extractNetworkPortion(msg.getRecipientAddressing()); } else if (MceStateMachine.FOLDER_SENT.equals(folderName)) { diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java index d5c15b63f4b..44a163c4109 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java @@ -86,7 +86,7 @@ public class BluetoothOppManager { @VisibleForTesting String mMimeTypeOfSendingFiles; - @VisibleForTesting ArrayList mUrisOfSendingFiles; + @VisibleForTesting List mUrisOfSendingFiles; private boolean mIsHandoverInitiated; @@ -104,7 +104,7 @@ public class BluetoothOppManager { private static final String MULTIPLE_FLAG = "MULTIPLE_FLAG"; - private static final String ARRAYLIST_ITEM_SEPERATOR = ";"; + private static final String ARRAYLIST_ITEM_SEPARATOR = ";"; @VisibleForTesting static final int ALLOWED_INSERT_SHARE_THREAD_NUMBER = 3; @@ -221,7 +221,7 @@ public class BluetoothOppManager { String strUris = settings.getString(FILE_URIS, null); mUrisOfSendingFiles = new ArrayList(); if (strUris != null) { - String[] splitUri = strUris.split(ARRAYLIST_ITEM_SEPERATOR); + String[] splitUri = strUris.split(ARRAYLIST_ITEM_SEPARATOR); for (int i = 0; i < splitUri.length; i++) { mUrisOfSendingFiles.add(Uri.parse(splitUri[i])); Log.v(TAG, "Uri in batch: " + Uri.parse(splitUri[i])); @@ -243,7 +243,7 @@ public class BluetoothOppManager { for (int i = 0, count = mUrisOfSendingFiles.size(); i < count; i++) { Uri uriContent = mUrisOfSendingFiles.get(i); sb.append(uriContent); - sb.append(ARRAYLIST_ITEM_SEPERATOR); + sb.append(ARRAYLIST_ITEM_SEPARATOR); } String strUris = sb.toString(); editor.putString(FILE_URIS, strUris); @@ -280,7 +280,7 @@ public class BluetoothOppManager { } public void saveSendingFileInfo( - String mimeType, ArrayList uris, boolean isHandover, boolean fromExternal) + String mimeType, List uris, boolean isHandover, boolean fromExternal) throws IllegalArgumentException { synchronized (BluetoothOppManager.this) { mMultipleFlag = true; @@ -406,7 +406,7 @@ public class BluetoothOppManager { private final String mTypeOfMultipleFiles; - private final ArrayList mUris; + private final List mUris; private final boolean mIsMultiple; @@ -418,7 +418,7 @@ public class BluetoothOppManager { String typeOfSingleFile, String uri, String typeOfMultipleFiles, - ArrayList uris, + List uris, boolean handoverInitiated) { super("Insert ShareInfo Thread"); this.mRemoteDevice = device; diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java index 32bbe515c05..b749b34ddd1 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppUtility.java @@ -157,8 +157,8 @@ public class BluetoothOppUtility { /** Organize Array list for transfers in one batch */ // This function is used when UI show batch transfer. Currently only show single transfer. - public static ArrayList queryTransfersInBatch(Context context, Long timeStamp) { - ArrayList uris = new ArrayList(); + public static List queryTransfersInBatch(Context context, Long timeStamp) { + List uris = new ArrayList<>(); final String where = BluetoothShare.TIMESTAMP + " == " + timeStamp; Cursor metadataCursor = BluetoothMethodProxy.getInstance() diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java index 19c7b13e420..99bf3a859bb 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java @@ -47,6 +47,7 @@ import java.text.StringCharacterIterator; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.List; // Next tag value for ContentProfileErrorReportUtils.report(): 34 public class BluetoothPbapObexServer extends ServerRequestHandler { @@ -893,7 +894,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { } // Call history listing request } else { - ArrayList nameList = mVcardManager.loadCallHistoryList(appParamValue.needTag); + List nameList = mVcardManager.loadCallHistoryList(appParamValue.needTag); int requestSize = nameList.size() >= appParamValue.maxListCount ? appParamValue.maxListCount @@ -930,7 +931,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { ContactsType contactType) { int itemsFound = 0; - ArrayList nameList = null; + List nameList = null; if (mVcardSelector) { if (contactType == ContactsType.TYPE_PHONEBOOK) { nameList = @@ -971,10 +972,10 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { + appParamValue.searchValue); if (type.equals("number")) { - ArrayList savedPosList = new ArrayList<>(); - ArrayList selectedNameList = new ArrayList(); + List savedPosList = new ArrayList<>(); + List selectedNameList = new ArrayList(); // query the number, to get the names - ArrayList names = new ArrayList<>(); + List names = new ArrayList<>(); if (contactType == ContactsType.TYPE_PHONEBOOK) { names = mVcardManager.getContactNamesByNumber(appParamValue.searchValue); } else if (contactType == ContactsType.TYPE_SIM) { @@ -1005,8 +1006,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { } } else { - ArrayList savedPosList = new ArrayList<>(); - ArrayList selectedNameList = new ArrayList(); + List savedPosList = new ArrayList<>(); + List selectedNameList = new ArrayList(); if (appParamValue.searchValue != null) { compareValue = appParamValue.searchValue.trim().toLowerCase(); } diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java index bd3a5b58d49..c2dc364e556 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManager.java @@ -296,8 +296,8 @@ public class BluetoothPbapSimVcardManager { return size; } - public final ArrayList getSIMPhonebookNameList(final int orderByWhat) { - ArrayList nameList = new ArrayList(); + public final List getSIMPhonebookNameList(final int orderByWhat) { + List nameList = new ArrayList(); nameList.add(BluetoothPbapService.getLocalPhoneName()); // Since owner card should always be 0.vcf, maintain a separate list to avoid sorting ArrayList allnames = new ArrayList(); @@ -341,9 +341,9 @@ public class BluetoothPbapSimVcardManager { return nameList; } - public final ArrayList getSIMContactNamesByNumber(final String phoneNumber) { - ArrayList nameList = new ArrayList(); - ArrayList startNameList = new ArrayList(); + public final List getSIMContactNamesByNumber(final String phoneNumber) { + List nameList = new ArrayList(); + List startNameList = new ArrayList(); Cursor contactCursor = null; try { diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java index c91219abf5e..1574686d45f 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapUtils.java @@ -47,6 +47,7 @@ import java.util.Arrays; import java.util.Calendar; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Objects; import java.util.concurrent.atomic.AtomicLong; @@ -83,9 +84,9 @@ class BluetoothPbapUtils { private static class ContactData { private String mName; - private ArrayList mEmail; - private ArrayList mPhone; - private ArrayList mAddress; + private List mEmail; + private List mPhone; + private List mAddress; ContactData() { mPhone = new ArrayList<>(); @@ -93,11 +94,7 @@ class BluetoothPbapUtils { mAddress = new ArrayList<>(); } - ContactData( - String name, - ArrayList phone, - ArrayList email, - ArrayList address) { + ContactData(String name, List phone, List email, List address) { this.mName = name; this.mPhone = phone; this.mEmail = email; @@ -387,9 +384,9 @@ class BluetoothPbapUtils { } else { for (String contact : updatedList) { sPrimaryVersionCounter++; - ArrayList phoneTmp = new ArrayList<>(); - ArrayList emailTmp = new ArrayList<>(); - ArrayList addressTmp = new ArrayList<>(); + List phoneTmp = new ArrayList<>(); + List emailTmp = new ArrayList<>(); + List addressTmp = new ArrayList<>(); String nameTmp = null; boolean updated = false; @@ -480,7 +477,7 @@ class BluetoothPbapUtils { * Field update can be a field updated/added/deleted in an existing contact. * Returns true if any contact field is updated else return false. */ @VisibleForTesting - static boolean checkFieldUpdates(ArrayList oldFields, ArrayList newFields) { + static boolean checkFieldUpdates(List oldFields, List newFields) { if (newFields != null && oldFields != null) { if (newFields.size() != oldFields.size()) { sTotalSvcFields += Math.abs(newFields.size() - oldFields.size()); diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java index fd998b13c0a..a512254e6c5 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java @@ -52,6 +52,7 @@ import com.android.vcard.VCardPhoneNumberTranslationCallback; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; +import java.util.List; // Next tag value for ContentProfileErrorReportUtils.report(): 22 public class BluetoothPbapVcardManager { @@ -230,7 +231,7 @@ public class BluetoothPbapVcardManager { @VisibleForTesting static final int CALLS_NAME_COLUMN_INDEX = 1; @VisibleForTesting static final int CALLS_NUMBER_PRESENTATION_COLUMN_INDEX = 2; - public final ArrayList loadCallHistoryList(final int type) { + public final List loadCallHistoryList(final int type) { final Uri myUri = CallLog.Calls.CONTENT_URI; String selection = BluetoothPbapObexServer.createSelectionPara(type); String[] projection = @@ -280,8 +281,8 @@ public class BluetoothPbapVcardManager { return list; } - public final ArrayList getPhonebookNameList(final int orderByWhat) { - ArrayList nameList = new ArrayList(); + public final List getPhonebookNameList(final int orderByWhat) { + List nameList = new ArrayList(); // Owner vCard enhancement. Use "ME" profile if configured String ownerName = null; if (BluetoothPbapConfig.useProfileForOwnerVcard()) { @@ -339,14 +340,14 @@ public class BluetoothPbapVcardManager { return nameList; } - final ArrayList getSelectedPhonebookNameList( + final List getSelectedPhonebookNameList( final int orderByWhat, final boolean vcardType21, int needSendBody, int pbSize, byte[] selector, String vCardSelectorOperator) { - ArrayList nameList = new ArrayList(); + List nameList = new ArrayList(); PropertySelector vcardselector = new PropertySelector(selector); int vcardType; @@ -479,8 +480,8 @@ public class BluetoothPbapVcardManager { return nameList; } - public final ArrayList getContactNamesByNumber(final String phoneNumber) { - ArrayList nameList = new ArrayList(); + public final List getContactNamesByNumber(final String phoneNumber) { + List nameList = new ArrayList(); Cursor contactCursor = null; Uri uri = null; @@ -1447,7 +1448,7 @@ public class BluetoothPbapVcardManager { * given cursor is sorted by CONTACT_ID. */ private static void appendDistinctNameIdList( - ArrayList resultList, String defaultName, Cursor cursor) { + List resultList, String defaultName, Cursor cursor) { final int contactIdColumn = cursor.getColumnIndex(Data.CONTACT_ID); final int idColumn = cursor.getColumnIndex(Data._ID); final int nameColumn = cursor.getColumnIndex(Data.DISPLAY_NAME); diff --git a/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapRequest.java b/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapRequest.java index dd0dee2b6cd..77e266e2b15 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapRequest.java +++ b/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapRequest.java @@ -91,7 +91,7 @@ abstract class BluetoothPbapRequest { checkResponseCode(mResponseCode); } catch (IOException e) { - Log.e(TAG, "IOException occured when processing request", e); + Log.e(TAG, "IOException occurred when processing request", e); mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; throw e; @@ -105,7 +105,7 @@ abstract class BluetoothPbapRequest { try { mOp.abort(); } catch (IOException e) { - Log.e(TAG, "Exception occured when trying to abort", e); + Log.e(TAG, "Exception occurred when trying to abort", e); } } } @@ -119,12 +119,12 @@ abstract class BluetoothPbapRequest { protected void readResponseHeaders(HeaderSet headerset) { Log.v(TAG, "readResponseHeaders"); - /* nothing here by dafault */ + /* nothing here by default */ } protected void checkResponseCode(int responseCode) throws IOException { Log.v(TAG, "checkResponseCode"); - /* nothing here by dafault */ + /* nothing here by default */ } } diff --git a/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBook.java b/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBook.java index 998309dfc1d..becb7e6a41e 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBook.java +++ b/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBook.java @@ -25,7 +25,7 @@ import com.android.vcard.VCardEntry; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; +import java.util.List; final class BluetoothPbapRequestPullPhoneBook extends BluetoothPbapRequest { private static final String TAG = "PbapClient.PullPb"; @@ -112,7 +112,7 @@ final class BluetoothPbapRequestPullPhoneBook extends BluetoothPbapRequest { } } - public ArrayList getList() { + public List getList() { return mResponse.getList(); } diff --git a/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardList.java b/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardList.java index 96f960ad71d..e2b703a080c 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardList.java +++ b/android/app/src/com/android/bluetooth/pbapclient/BluetoothPbapVcardList.java @@ -33,13 +33,14 @@ import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.List; class BluetoothPbapVcardList { private static final String TAG = BluetoothPbapVcardList.class.getSimpleName(); // {@link BufferedInputStream#DEFAULT_BUFFER_SIZE} is not public private static final int BIS_DEFAULT_BUFFER_SIZE = 8192; - private final ArrayList mCards = new ArrayList(); + private final List mCards = new ArrayList(); private final Account mAccount; class CardEntryHandler implements VCardEntryHandler { @@ -135,7 +136,7 @@ class BluetoothPbapVcardList { return mCards.size(); } - public ArrayList getList() { + public List getList() { return mCards; } diff --git a/android/app/src/com/android/bluetooth/pbapclient/CallLogPullRequest.java b/android/app/src/com/android/bluetooth/pbapclient/CallLogPullRequest.java index 16256710d2b..9e3499d66a1 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/CallLogPullRequest.java +++ b/android/app/src/com/android/bluetooth/pbapclient/CallLogPullRequest.java @@ -37,8 +37,8 @@ import com.android.vcard.VCardEntry.PhoneData; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; +import java.util.Map; public class CallLogPullRequest extends PullRequest { private static final String TAG = "CallLogPullRequest"; @@ -48,10 +48,10 @@ public class CallLogPullRequest extends PullRequest { private final Account mAccount; private Context mContext; - private HashMap mCallCounter; + private Map mCallCounter; public CallLogPullRequest( - Context context, String path, HashMap map, Account account) { + Context context, String path, Map map, Account account) { mContext = context; this.path = path; mCallCounter = map; diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java index f442d5f23a1..e053ef1def4 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java +++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java @@ -39,8 +39,9 @@ import com.android.obex.ResponseCodes; import com.android.vcard.VCardEntry; import java.io.IOException; -import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; /* Bluetooth/pbapclient/PbapClientConnectionHandler is responsible * for connecting, disconnecting and downloading contacts from the @@ -255,7 +256,7 @@ class PbapClientConnectionHandler extends Handler { downloadContacts(SIM_PB_PATH); } - HashMap callCounter = new HashMap<>(); + Map callCounter = new HashMap<>(); downloadCallLog(MCH_PATH, callCounter); downloadCallLog(ICH_PATH, callCounter); downloadCallLog(OCH_PATH, callCounter); @@ -406,7 +407,7 @@ class PbapClientConnectionHandler extends Handler { numberOfContactsToDownload, startOffset); request.execute(mObexSession); - ArrayList vcards = request.getList(); + List vcards = request.getList(); if (path == FAV_PATH) { // mark each vcard as a favorite for (VCardEntry v : vcards) { @@ -430,7 +431,7 @@ class PbapClientConnectionHandler extends Handler { } @VisibleForTesting - void downloadCallLog(String path, HashMap callCounter) { + void downloadCallLog(String path, Map callCounter) { try { BluetoothPbapRequestPullPhoneBook request = new BluetoothPbapRequestPullPhoneBook(path, mAccount, 0, VCARD_TYPE_30, 0, 0); diff --git a/android/app/src/com/android/bluetooth/sap/SapRilReceiverHidl.java b/android/app/src/com/android/bluetooth/sap/SapRilReceiverHidl.java index 4546aecca96..9d153bfa871 100644 --- a/android/app/src/com/android/bluetooth/sap/SapRilReceiverHidl.java +++ b/android/app/src/com/android/bluetooth/sap/SapRilReceiverHidl.java @@ -29,8 +29,9 @@ import java.util.List; import java.util.concurrent.atomic.AtomicLong; /** SapRiilReceiverHidl is the HIDL implementation of ISapRilReceiver */ +@SuppressWarnings("NonApiType") // We cannot change hidl anymore public class SapRilReceiverHidl implements ISapRilReceiver { - private static final String TAG = "SapRilReceiver"; + private static final String TAG = "SapRilReceiverHidl"; // todo: add support for slot2 and slot3 private static final String SERVICE_NAME_RIL_BT = "slot1"; diff --git a/android/app/src/com/android/bluetooth/tbs/TbsGeneric.java b/android/app/src/com/android/bluetooth/tbs/TbsGeneric.java index 3af5a91e787..93e42d9bed2 100644 --- a/android/app/src/com/android/bluetooth/tbs/TbsGeneric.java +++ b/android/app/src/com/android/bluetooth/tbs/TbsGeneric.java @@ -44,6 +44,7 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TreeMap; import java.util.UUID; @@ -1058,8 +1059,7 @@ public class TbsGeneric { return null; } - private synchronized Map.Entry getCallByStates( - LinkedHashSet states) { + private synchronized Map.Entry getCallByStates(Set states) { for (Map.Entry entry : mCurrentCallsList.entrySet()) { if (states.contains(entry.getValue().getState())) { return entry; diff --git a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java index 7f372008b16..852b7139de4 100644 --- a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java +++ b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java @@ -60,6 +60,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; import java.util.Queue; +import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; import java.util.TreeMap; @@ -1430,7 +1431,7 @@ public class BluetoothInCallService extends InCallService { return null; } - public BluetoothCall getCallByStates(LinkedHashSet states) { + public BluetoothCall getCallByStates(Set states) { List calls = getBluetoothCalls(); for (BluetoothCall call : calls) { if (states.contains(call.getState())) { diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java index c85bb8b5b70..2eeadc299aa 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapSmsPduTest.java @@ -42,7 +42,7 @@ import org.mockito.junit.MockitoRule; import java.io.ByteArrayInputStream; import java.io.InputStream; -import java.util.ArrayList; +import java.util.List; @SmallTest @RunWith(AndroidJUnit4.class) @@ -107,7 +107,7 @@ public class BluetoothMapSmsPduTest { Assume.assumeTrue(mSmsManager.isImsSmsSupported()); when(mTelephonyManager.getCurrentPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_GSM); - ArrayList pdus = + List pdus = BluetoothMapSmsPdu.getSubmitPdus( mTargetContext, TEST_TEXT_WITH_TWO_SMS_PARTS, null); @@ -136,7 +136,7 @@ public class BluetoothMapSmsPduTest { Assume.assumeTrue(mSmsManager.isImsSmsSupported()); when(mTelephonyManager.getCurrentPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_CDMA); - ArrayList pdus = BluetoothMapSmsPdu.getSubmitPdus(mTargetContext, TEST_TEXT, null); + List pdus = BluetoothMapSmsPdu.getSubmitPdus(mTargetContext, TEST_TEXT, null); assertThat(pdus.size()).isEqualTo(1); assertThat(pdus.get(0).getType()).isEqualTo(BluetoothMapSmsPdu.SMS_TYPE_CDMA); @@ -161,7 +161,7 @@ public class BluetoothMapSmsPduTest { Assume.assumeTrue(mSmsManager.isImsSmsSupported()); when(mTelephonyManager.getCurrentPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_GSM); - ArrayList pdus = + List pdus = BluetoothMapSmsPdu.getDeliverPdus( mTargetContext, TEST_TEXT, TEST_DESTINATION_ADDRESS, TEST_DATE); @@ -190,7 +190,7 @@ public class BluetoothMapSmsPduTest { Assume.assumeTrue(mSmsManager.isImsSmsSupported()); when(mTelephonyManager.getCurrentPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_CDMA); - ArrayList pdus = + List pdus = BluetoothMapSmsPdu.getDeliverPdus( mTargetContext, TEST_TEXT, TEST_DESTINATION_ADDRESS, TEST_DATE); 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 e1e8c20cc12..e55117a037e 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 @@ -34,7 +34,7 @@ import org.junit.runner.RunWith; import java.io.ByteArrayInputStream; import java.io.InputStream; -import java.util.ArrayList; +import java.util.List; @SmallTest @RunWith(AndroidJUnit4.class) @@ -45,7 +45,7 @@ public class BluetoothMapbMessageSmsTest { private SmsManager mSmsManager = SmsManager.getDefault(); private Context mTargetContext; - private ArrayList TEST_SMS_BODY_PDUS; + private List TEST_SMS_BODY_PDUS; @Before public void setUp() throws Exception { diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java index 9af7c38e32f..d10246229b5 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppUtilityTest.java @@ -58,7 +58,6 @@ import org.mockito.Spy; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; -import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; @@ -150,8 +149,7 @@ public class BluetoothOppUtilityTest { doAnswer(invocation -> cnt.incrementAndGet() > 5).when(mCursor).isAfterLast(); doReturn(CORRECT_FORMAT_BUT_INVALID_FILE_URI.toString()).when(mCursor).getString(0); - ArrayList answer = - BluetoothOppUtility.queryTransfersInBatch(mContext, timestampValue); + List answer = BluetoothOppUtility.queryTransfersInBatch(mContext, timestampValue); for (String url : answer) { assertThat(url).isEqualTo(CORRECT_FORMAT_BUT_INVALID_FILE_URI.toString()); } diff --git a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java index d9cb6b3e61f..887a4a42a9b 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/pbap/BluetoothPbapSimVcardManagerTest.java @@ -290,10 +290,10 @@ public class BluetoothPbapSimVcardManagerTest { return nameList.get(currentPosition.get()); }); - ArrayList result = + List result = mManager.getSIMPhonebookNameList(BluetoothPbapObexServer.ORDER_BY_INDEXED); - ArrayList expectedResult = new ArrayList<>(); + List expectedResult = new ArrayList<>(); expectedResult.add(localPhoneName); expectedResult.addAll(nameList); diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java index c20b458b330..d48087b59f4 100644 --- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java +++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java @@ -106,6 +106,7 @@ import java.time.Duration; import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -134,7 +135,7 @@ class BluetoothManagerService { private static final int TIMEOUT_BIND_MS = 4000 * HW_MULTIPLIER; // Timeout value for synchronous binder call - private static final Duration STATE_TIMEOUT = Duration.ofSeconds(4 * HW_MULTIPLIER); + private static final Duration STATE_TIMEOUT = Duration.ofSeconds(4L * HW_MULTIPLIER); // Maximum msec to wait for service restart private static final int SERVICE_RESTART_TIME_MS = 400 * HW_MULTIPLIER; @@ -252,8 +253,10 @@ class BluetoothManagerService { } } + @SuppressWarnings("NonApiType") private final LinkedList mActiveLogs = new LinkedList<>(); - private final LinkedList mCrashTimestamps = new LinkedList<>(); + + private final List mCrashTimestamps = new ArrayList<>(); private int mCrashes = 0; private long mLastEnabledTime; @@ -2215,7 +2218,7 @@ class BluetoothManagerService { private void addCrashLog() { synchronized (mCrashTimestamps) { if (mCrashTimestamps.size() == CRASH_LOG_MAX_SIZE) { - mCrashTimestamps.removeFirst(); + mCrashTimestamps.remove(0); } mCrashTimestamps.add(System.currentTimeMillis()); mCrashes++; -- GitLab From fa6fb000fad70c32f72bfbec2e62b7da6c638a36 Mon Sep 17 00:00:00 2001 From: William Escande Date: Mon, 10 Jun 2024 19:31:18 -0700 Subject: [PATCH 0054/1446] ErrorProne: Enforce & fix StringCharset See https://errorprone.info/bugpattern/StringCharset Bug: 344658662 Test: m BluetoothInstrumentationTests Flag: Exempt Build and test only Change-Id: I33cd96234d625f4e78fdafb172a85aa813acec66 --- android/app/Android.bp | 1 + .../com/android/bluetooth/SignedLongLong.java | 4 +- .../bip/BipImageDescriptor.java | 10 ++-- .../bip/BipImageProperties.java | 38 ++++---------- .../bluetooth/btservice/RemoteDevices.java | 14 ++--- .../bluetooth/gatt/AdvertiseHelper.java | 35 ++++++------- .../bluetooth/map/BluetoothMapAppParams.java | 44 ++++++++-------- .../bluetooth/map/BluetoothMapContent.java | 46 +++++++---------- .../map/BluetoothMapContentObserver.java | 37 ++++---------- .../map/BluetoothMapConvoContactElement.java | 16 +----- .../map/BluetoothMapConvoListing.java | 7 ++- .../map/BluetoothMapConvoListingElement.java | 13 +---- .../map/BluetoothMapFolderElement.java | 10 ++-- .../map/BluetoothMapMessageListing.java | 10 ++-- .../bluetooth/map/BluetoothMapSmsPdu.java | 6 +-- .../bluetooth/map/BluetoothMapUtils.java | 46 +++++------------ .../bluetooth/map/BluetoothMapbMessage.java | 34 +++++-------- .../map/BluetoothMapbMessageEmail.java | 9 ++-- .../map/BluetoothMapbMessageMime.java | 51 +++++-------------- .../map/BluetoothMapbMessageSms.java | 9 ++-- .../opp/BluetoothOppReceiveFileInfo.java | 19 ++----- 21 files changed, 158 insertions(+), 301 deletions(-) diff --git a/android/app/Android.bp b/android/app/Android.bp index b8b50fbacf0..f2f0a70927c 100644 --- a/android/app/Android.bp +++ b/android/app/Android.bp @@ -332,6 +332,7 @@ android_app { "-Xep:NonApiType:ERROR", "-Xep:NonCanonicalType:ERROR", "-Xep:ReturnAtTheEndOfVoidFunction:ERROR", + "-Xep:StringCharset:ERROR", "-Xep:UnusedMethod:ERROR", "-Xep:UnusedVariable:ERROR", "-XepExcludedPaths:.*/srcjars/.*", // Exclude generated files diff --git a/android/app/src/com/android/bluetooth/SignedLongLong.java b/android/app/src/com/android/bluetooth/SignedLongLong.java index c84757f1f8d..023d4b0e8f2 100644 --- a/android/app/src/com/android/bluetooth/SignedLongLong.java +++ b/android/app/src/com/android/bluetooth/SignedLongLong.java @@ -17,7 +17,6 @@ package com.android.bluetooth; import com.android.bluetooth.map.BluetoothMapUtils; -import java.io.UnsupportedEncodingException; import java.util.Objects; /** @@ -40,11 +39,10 @@ public class SignedLongLong implements Comparable { * * @param value the hex-string * @return the created object - * @throws UnsupportedEncodingException if "US-ASCII" charset is not supported, * @throws NullPointerException if the string {@code value} is null, * @throws NumberFormatException if the string {@code value} contains invalid characters. */ - public static SignedLongLong fromString(String value) throws UnsupportedEncodingException { + public static SignedLongLong fromString(String value) { String lsbStr, msbStr; long msb = 0; diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java index c38019b1284..3eae52076ad 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java @@ -27,11 +27,11 @@ import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; /** * Contains the metadata that describes either (1) the desired size of a image to be downloaded or - * (2) the extact size of an image to be uploaded. + * (2) the exact size of an image to be uploaded. * *

When using this to assert the size of an image to download/pull, it's best to derive this * specific descriptor from any of the available BipImageFormat options returned from a @@ -245,11 +245,7 @@ public class BipImageDescriptor { */ public byte[] serialize() { String s = toString(); - try { - return s != null ? s.getBytes("UTF-8") : null; - } catch (UnsupportedEncodingException e) { - return null; - } + return s != null ? s.getBytes(StandardCharsets.UTF_8) : null; } @Override diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java index 44a56579074..e49d9dd5a91 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java @@ -27,7 +27,7 @@ import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -198,7 +198,7 @@ public class BipImageProperties { new BipAttachmentFormat( contentType, charset, name, size, created, modified)); } else { - warn("Unrecognized tag in x-bt/img-properties object: " + tag); + Log.w(TAG, "Unrecognized tag in x-bt/img-properties object: " + tag); } break; case XmlPullParser.END_TAG: @@ -208,9 +208,9 @@ public class BipImageProperties { } return; } catch (XmlPullParserException e) { - error("XML parser error when parsing XML", e); + Log.e(TAG, "XML parser error when parsing XML", e); } catch (IOException e) { - error("I/O error when parsing XML", e); + Log.e(TAG, "I/O error when parsing XML", e); } throw new ParseException("Failed to parse image-properties from stream"); } @@ -317,7 +317,7 @@ public class BipImageProperties { BipPixel pixel = format.getPixel(); int size = format.getSize(); if (encoding == null || pixel == null) { - error("Native format " + format.toString() + " is invalid."); + Log.e(TAG, "Native format " + format.toString() + " is invalid."); continue; } xmlMsgElement.startTag(null, "native"); @@ -335,7 +335,7 @@ public class BipImageProperties { int maxSize = format.getMaxSize(); BipTransformation trans = format.getTransformation(); if (encoding == null || pixel == null) { - error("Variant format " + format.toString() + " is invalid."); + Log.e(TAG, "Variant format " + format.toString() + " is invalid."); continue; } xmlMsgElement.startTag(null, "variant"); @@ -358,7 +358,7 @@ public class BipImageProperties { BipDateTime created = format.getCreatedDate(); BipDateTime modified = format.getModifiedDate(); if (contentType == null || name == null) { - error("Attachment format " + format.toString() + " is invalid."); + Log.e(TAG, "Attachment format " + format.toString() + " is invalid."); continue; } xmlMsgElement.startTag(null, "attachment"); @@ -383,11 +383,11 @@ public class BipImageProperties { xmlMsgElement.endDocument(); return writer.toString(); } catch (IllegalArgumentException e) { - error("Falied to serialize ImageProperties", e); + Log.e(TAG, "Failed to serialize ImageProperties", e); } catch (IllegalStateException e) { - error("Falied to serialize ImageProperties", e); + Log.e(TAG, "Failed to serialize ImageProperties", e); } catch (IOException e) { - error("Falied to serialize ImageProperties", e); + Log.e(TAG, "Failed to serialize ImageProperties", e); } return null; } @@ -402,11 +402,7 @@ public class BipImageProperties { public byte[] serialize() { if (!isValid()) return null; String s = toString(); - try { - return s != null ? s.getBytes("UTF-8") : null; - } catch (UnsupportedEncodingException e) { - return null; - } + return s != null ? s.getBytes(StandardCharsets.UTF_8) : null; } /** @@ -419,16 +415,4 @@ public class BipImageProperties { public boolean isValid() { return sVersion.equals(mVersion) && mImageHandle != null && mHasThumbnailFormat; } - - private static void warn(String msg) { - Log.w(TAG, msg); - } - - private static void error(String msg) { - Log.e(TAG, msg); - } - - private static void error(String msg, Throwable e) { - Log.e(TAG, msg, e); - } } diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java index f0c46448bd4..48e769b99c1 100644 --- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java +++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java @@ -53,7 +53,7 @@ import com.android.bluetooth.flags.Flags; import com.android.bluetooth.hfp.HeadsetHalConstants; import com.android.internal.annotations.VisibleForTesting; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashMap; @@ -667,14 +667,10 @@ public class RemoteDevices { public void setModelName(String modelName) { mModelName = modelName; - try { - mAdapterService.setMetadata( - this.mDevice, - BluetoothDevice.METADATA_MODEL_NAME, - mModelName.getBytes("UTF-8")); - } catch (UnsupportedEncodingException uee) { - Log.e(TAG, "setModelName: UTF-8 not supported?!?"); // this should not happen - } + mAdapterService.setMetadata( + this.mDevice, + BluetoothDevice.METADATA_MODEL_NAME, + mModelName.getBytes(StandardCharsets.UTF_8)); } /** diff --git a/android/app/src/com/android/bluetooth/gatt/AdvertiseHelper.java b/android/app/src/com/android/bluetooth/gatt/AdvertiseHelper.java index cd99fb87fba..51f5bb97856 100644 --- a/android/app/src/com/android/bluetooth/gatt/AdvertiseHelper.java +++ b/android/app/src/com/android/bluetooth/gatt/AdvertiseHelper.java @@ -23,6 +23,7 @@ import android.os.ParcelUuid; import android.util.Log; import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; class AdvertiseHelper { @@ -56,27 +57,23 @@ class AdvertiseHelper { ByteArrayOutputStream ret = new ByteArrayOutputStream(); if (data.getIncludeDeviceName()) { - try { - byte[] nameBytes = name.getBytes("UTF-8"); - - int nameLength = nameBytes.length; - byte type; - - // TODO(jpawlowski) put a better limit on device name! - if (nameLength > DEVICE_NAME_MAX) { - nameLength = DEVICE_NAME_MAX; - type = SHORTENED_LOCAL_NAME; - } else { - type = COMPLETE_LOCAL_NAME; - } + byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8); + + int nameLength = nameBytes.length; + byte type; - check_length(type, nameLength + 1); - ret.write(nameLength + 1); - ret.write(type); - ret.write(nameBytes, 0, nameLength); - } catch (java.io.UnsupportedEncodingException e) { - Log.e(TAG, "Can't include name - encoding error!", e); + // TODO(jpawlowski) put a better limit on device name! + if (nameLength > DEVICE_NAME_MAX) { + nameLength = DEVICE_NAME_MAX; + type = SHORTENED_LOCAL_NAME; + } else { + type = COMPLETE_LOCAL_NAME; } + + check_length(type, nameLength + 1); + ret.write(nameLength + 1); + ret.write(type); + ret.write(nameBytes, 0, nameLength); } for (int i = 0; i < data.getManufacturerSpecificData().size(); i++) { diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java b/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java index 630a90e4d87..0cbc19be049 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapAppParams.java @@ -22,9 +22,9 @@ import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.SignedLongLong; import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; -import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -941,23 +941,22 @@ public class BluetoothMapAppParams { * Get the approximate length needed to store the appParameters in a byte array. * * @return the length in bytes - * @throws UnsupportedEncodingException if the platform does not support UTF-8 encoding. */ - private int getParamMaxLength() throws UnsupportedEncodingException { + private int getParamMaxLength() { int length = 0; length += 38 * 2; // tagId + tagLength length += 33 + 4 * 16; // fixed sizes TODO: Update when spec is ready length += getFilterPeriodBegin() == INVALID_VALUE_PARAMETER ? 0 : 20; length += getFilterPeriodEnd() == INVALID_VALUE_PARAMETER ? 0 : 20; if (getFilterRecipient() != null) { - length += getFilterRecipient().getBytes("UTF-8").length; + length += getFilterRecipient().getBytes(StandardCharsets.UTF_8).length; } if (getFilterOriginator() != null) { - length += getFilterOriginator().getBytes("UTF-8").length; + length += getFilterOriginator().getBytes(StandardCharsets.UTF_8).length; } length += getMseTime() == INVALID_VALUE_PARAMETER ? 0 : 20; if (getPresenceStatus() != null) { - length += getPresenceStatus().getBytes("UTF-8").length; + length += getPresenceStatus().getBytes(StandardCharsets.UTF_8).length; } length += (getLastActivity() == INVALID_VALUE_PARAMETER) ? 0 : 20; return length; @@ -967,9 +966,8 @@ public class BluetoothMapAppParams { * Encode the application parameter object to a byte array. * * @return a byte Array representation of the application parameter object. - * @throws UnsupportedEncodingException if the platform does not support UTF-8 encoding. */ - public byte[] encodeParams() throws UnsupportedEncodingException { + public byte[] encodeParams() { ByteBuffer appParamBuf = ByteBuffer.allocate(getParamMaxLength()); appParamBuf.order(ByteOrder.BIG_ENDIAN); byte[] retBuf; @@ -991,13 +989,15 @@ public class BluetoothMapAppParams { } if (getFilterPeriodBegin() != INVALID_VALUE_PARAMETER) { appParamBuf.put((byte) FILTER_PERIOD_BEGIN); - appParamBuf.put((byte) getFilterPeriodBeginString().getBytes("UTF-8").length); - appParamBuf.put(getFilterPeriodBeginString().getBytes("UTF-8")); + appParamBuf.put( + (byte) getFilterPeriodBeginString().getBytes(StandardCharsets.UTF_8).length); + appParamBuf.put(getFilterPeriodBeginString().getBytes(StandardCharsets.UTF_8)); } if (getFilterPeriodEnd() != INVALID_VALUE_PARAMETER) { appParamBuf.put((byte) FILTER_PERIOD_END); - appParamBuf.put((byte) getFilterPeriodEndString().getBytes("UTF-8").length); - appParamBuf.put(getFilterPeriodEndString().getBytes("UTF-8")); + appParamBuf.put( + (byte) getFilterPeriodEndString().getBytes(StandardCharsets.UTF_8).length); + appParamBuf.put(getFilterPeriodEndString().getBytes(StandardCharsets.UTF_8)); } if (getFilterReadStatus() != INVALID_VALUE_PARAMETER) { appParamBuf.put((byte) FILTER_READ_STATUS); @@ -1006,13 +1006,13 @@ public class BluetoothMapAppParams { } if (getFilterRecipient() != null) { appParamBuf.put((byte) FILTER_RECIPIENT); - appParamBuf.put((byte) getFilterRecipient().getBytes("UTF-8").length); - appParamBuf.put(getFilterRecipient().getBytes("UTF-8")); + appParamBuf.put((byte) getFilterRecipient().getBytes(StandardCharsets.UTF_8).length); + appParamBuf.put(getFilterRecipient().getBytes(StandardCharsets.UTF_8)); } if (getFilterOriginator() != null) { appParamBuf.put((byte) FILTER_ORIGINATOR); - appParamBuf.put((byte) getFilterOriginator().getBytes("UTF-8").length); - appParamBuf.put(getFilterOriginator().getBytes("UTF-8")); + appParamBuf.put((byte) getFilterOriginator().getBytes(StandardCharsets.UTF_8).length); + appParamBuf.put(getFilterOriginator().getBytes(StandardCharsets.UTF_8)); } if (getFilterPriority() != INVALID_VALUE_PARAMETER) { appParamBuf.put((byte) FILTER_PRIORITY); @@ -1101,8 +1101,8 @@ public class BluetoothMapAppParams { } if (getMseTime() != INVALID_VALUE_PARAMETER) { appParamBuf.put((byte) MSE_TIME); - appParamBuf.put((byte) getMseTimeString().getBytes("UTF-8").length); - appParamBuf.put(getMseTimeString().getBytes("UTF-8")); + appParamBuf.put((byte) getMseTimeString().getBytes(StandardCharsets.UTF_8).length); + appParamBuf.put(getMseTimeString().getBytes(StandardCharsets.UTF_8)); } // Note: New for IM if (getDatabaseIdentifier() != null) { @@ -1122,12 +1122,12 @@ public class BluetoothMapAppParams { } if (getPresenceStatus() != null) { appParamBuf.put((byte) PRESENCE_TEXT); - appParamBuf.put((byte) getPresenceStatus().getBytes("UTF-8").length); + appParamBuf.put((byte) getPresenceStatus().getBytes(StandardCharsets.UTF_8).length); appParamBuf.put(getPresenceStatus().getBytes()); } if (getLastActivity() != INVALID_VALUE_PARAMETER) { appParamBuf.put((byte) LAST_ACTIVITY); - appParamBuf.put((byte) getLastActivityString().getBytes("UTF-8").length); + appParamBuf.put((byte) getLastActivityString().getBytes(StandardCharsets.UTF_8).length); appParamBuf.put(getLastActivityString().getBytes()); } if (getChatState() != INVALID_VALUE_PARAMETER) { @@ -1415,7 +1415,7 @@ public class BluetoothMapAppParams { public void setFilterMsgHandle(String handle) { try { mFilterMsgHandle = BluetoothMapUtils.getLongFromString(handle); - } catch (UnsupportedEncodingException | NumberFormatException e) { + } catch (NumberFormatException e) { ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, @@ -1473,7 +1473,7 @@ public class BluetoothMapAppParams { public void setFilterConvoId(String id) { try { mFilterConvoId = SignedLongLong.fromString(id); - } catch (UnsupportedEncodingException | NumberFormatException e) { + } catch (NumberFormatException e) { ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, BluetoothProtoEnums.BLUETOOTH_MAP_APP_PARAMS, diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java b/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java index a04e86108ae..205c896533f 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java @@ -59,6 +59,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -3280,7 +3281,7 @@ public class BluetoothMapContent { if (summary != null && cs != null && !cs.equals("UTF-8")) { try { // TODO: Not sure this is how to convert to UTF-8 - summary = new String(summary.getBytes(cs), "UTF-8"); + summary = new String(summary.getBytes(cs), StandardCharsets.UTF_8); } catch (UnsupportedEncodingException e) { ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, @@ -3899,33 +3900,23 @@ public class BluetoothMapContent { if (!part.mContentType.toUpperCase().contains("TEXT") && !message.getIncludeAttachments()) { StringBuilder sb = new StringBuilder(); - try { - part.encodePlainText(sb); - // Each time {@code encodePlainText} is called, it adds {@code "\r\n"} - // to the string. {@code encodePlainText} is called here to replace - // an image with a string, but later on, when we encode the entire - // bMessage in {@link BluetoothMapbMessageMime#encode()}, - // {@code encodePlainText} will be called again on this {@code - // MimePart} (as text this time), adding a second {@code "\r\n"}. So - // we remove the extra newline from the end. - int newlineIndex = sb.lastIndexOf("\r\n"); - if (newlineIndex != -1) sb.delete(newlineIndex, newlineIndex + 4); - text = sb.toString(); - part.mContentType = "text"; - } catch (UnsupportedEncodingException e) { - ContentProfileErrorReportUtils.report( - BluetoothProfile.MAP, - BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT, - BluetoothStatsLog - .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, - 6); - Log.d(TAG, "extractMmsParts", e); - } + part.encodePlainText(sb); + // Each time {@code encodePlainText} is called, it adds {@code "\r\n"} + // to the string. {@code encodePlainText} is called here to replace + // an image with a string, but later on, when we encode the entire + // bMessage in {@link BluetoothMapbMessageMime#encode()}, + // {@code encodePlainText} will be called again on this {@code + // MimePart} (as text this time), adding a second {@code "\r\n"}. So + // we remove the extra newline from the end. + int newlineIndex = sb.lastIndexOf("\r\n"); + if (newlineIndex != -1) sb.delete(newlineIndex, newlineIndex + 4); + text = sb.toString(); + part.mContentType = "text"; } try { if (text != null) { - part.mData = text.getBytes("UTF-8"); + part.mData = text.getBytes(StandardCharsets.UTF_8); part.mCharsetName = "utf-8"; } else { part.mData = @@ -4255,12 +4246,9 @@ public class BluetoothMapContent { * @param id the content provider id for the message to fetch. * @param appParams The application parameter object received from the client. * @return a byte[] containing the utf-8 encoded bMessage to send to the client. - * @throws UnsupportedEncodingException if UTF-8 is not supported, which is guaranteed to be - * supported on an android device */ public byte[] getIMMessage( - long id, BluetoothMapAppParams appParams, BluetoothMapFolderElement folderElement) - throws UnsupportedEncodingException { + long id, BluetoothMapAppParams appParams, BluetoothMapFolderElement folderElement) { long threadId, folderId; if (appParams.getCharset() == MAP_MESSAGE_CHARSET_NATIVE) { @@ -4324,7 +4312,7 @@ public class BluetoothMapContent { MimePart part = message.addMimePart(); part.mData = c.getString((c.getColumnIndex(BluetoothMapContract.MessageColumns.BODY))) - .getBytes("UTF-8"); + .getBytes(StandardCharsets.UTF_8); part.mCharsetName = "utf-8"; part.mContentId = "0"; part.mContentType = "text/plain"; diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java index 5c47fd566a2..2f8c8c941f7 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java @@ -74,7 +74,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.StringWriter; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; @@ -788,7 +788,7 @@ public class BluetoothMapContentObserver { } } - public byte[] encode() throws UnsupportedEncodingException { + public byte[] encode() { StringWriter sw = new StringWriter(); XmlSerializer xmlEvtReport = Xml.newSerializer(); @@ -915,7 +915,7 @@ public class BluetoothMapContentObserver { Log.v(TAG, sw.toString()); - return sw.toString().getBytes("UTF-8"); + return sw.toString().getBytes(StandardCharsets.UTF_8); } } @@ -994,7 +994,7 @@ public class BluetoothMapContentObserver { if (mMnsClient.isValidMnsRecord()) { msg.what = BluetoothMnsObexClient.MSG_MNS_NOTIFICATION_REGISTRATION; } else { - // Trigger SDP Search and notificaiton registration , if SDP record not found. + // Trigger SDP Search and notification registration , if SDP record not found. msg.what = BluetoothMnsObexClient.MSG_MNS_SDP_SEARCH_REGISTRATION; if (mMnsClient.mMnsLstRegRqst != null && (mMnsClient.mMnsLstRegRqst.isSearchInProgress())) { @@ -1304,17 +1304,7 @@ public class BluetoothMapContentObserver { } } - try { - mMnsClient.sendEvent(evt.encode(), mMasId); - } catch (UnsupportedEncodingException ex) { - ContentProfileErrorReportUtils.report( - BluetoothProfile.MAP, - BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, - BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, - 8); - /* do nothing */ - Log.w(TAG, "Exception encoding sendEvent response", ex); - } + mMnsClient.sendEvent(evt.encode(), mMasId); } @VisibleForTesting @@ -1680,7 +1670,7 @@ public class BluetoothMapContentObserver { if (threadId == DELETED_THREAD_ID) { // Message deleted // TODO: // We shall only use the folder attribute, but can't remember - // wether to set it to "deleted" or the name of the folder + // whether to set it to "deleted" or the name of the folder // from which the message have been deleted. // "old_folder" used only for MessageShift event Event evt = @@ -2648,7 +2638,7 @@ public class BluetoothMapContentObserver { /* Update the folder ID to avoid triggering an event for MCE * initiated actions. */ /* UPDATE: Actually the BT-Spec. states that an undelete is a move of the - * message to INBOX - clearified in errata 5591. + * message to INBOX - clarified in errata 5591. * Therefore we update the cache to INBOX-folderId - to trigger a message * shift event to the old-folder. */ if (inboxFolder != null) { @@ -2771,7 +2761,7 @@ public class BluetoothMapContentObserver { // after undelete. // We do this by changing the cached folder value to being inbox - hence // the event handler will se the update as the message have been shifted - // from INBOX to old-folder. (Errata 5591 clearifies this) + // from INBOX to old-folder. (Errata 5591 clarifies this) msg.type = Mms.MESSAGE_BOX_INBOX; } } @@ -2864,7 +2854,7 @@ public class BluetoothMapContentObserver { * after undelete. * We do this by changing the cached folder value to being inbox - hence * the event handler will se the update as the message have been shifted - * from INBOX to old-folder. (Errata 5591 clearifies this) + * from INBOX to old-folder. (Errata 5591 clarifies this) * */ msg.type = Sms.MESSAGE_TYPE_INBOX; } @@ -3618,7 +3608,7 @@ public class BluetoothMapContentObserver { } values.put(Mms.Part.FILENAME, "smil.xml"); values.put(Mms.Part.NAME, "smil.xml"); - values.put(Mms.Part.TEXT, new String(part.mData, "UTF-8")); + values.put(Mms.Part.TEXT, new String(part.mData, StandardCharsets.UTF_8)); uri = Uri.parse(Mms.CONTENT_URI + "/" + handle + "/part"); uri = mResolver.insert(uri, values); @@ -3638,13 +3628,6 @@ public class BluetoothMapContentObserver { } } } - } catch (UnsupportedEncodingException e) { - ContentProfileErrorReportUtils.report( - BluetoothProfile.MAP, - BluetoothProtoEnums.BLUETOOTH_MAP_CONTENT_OBSERVER, - BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, - 26); - Log.w(TAG, e); } catch (IOException e) { ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java index a75e65521ae..bc4fbd5efe5 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoContactElement.java @@ -14,20 +14,15 @@ */ package com.android.bluetooth.map; -import android.bluetooth.BluetoothProfile; -import android.bluetooth.BluetoothProtoEnums; import android.util.Log; -import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.SignedLongLong; -import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -92,16 +87,7 @@ public class BluetoothMapConvoContactElement this.mPresenceStatus = presenceStatus; this.mPriority = priority; if (btUid != null) { - try { - this.mBtUid = SignedLongLong.fromString(btUid); - } catch (UnsupportedEncodingException e) { - ContentProfileErrorReportUtils.report( - BluetoothProfile.MAP, - BluetoothProtoEnums.BLUETOOTH_MAP_CONVO_CONTACT_ELEMENT, - BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, - 0); - Log.w(TAG, e); - } + this.mBtUid = SignedLongLong.fromString(btUid); } } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListing.java b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListing.java index 4aa4e855804..20dd1761749 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListing.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListing.java @@ -30,7 +30,7 @@ import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.util.ArrayList; import java.util.Collections; @@ -91,9 +91,8 @@ public class BluetoothMapConvoListing { * a trimmed byte array * * @return a reference to the encoded byte array. - * @throws UnsupportedEncodingException if UTF-8 encoding is unsupported on the platform. */ - public byte[] encode() throws UnsupportedEncodingException { + public byte[] encode() { StringWriter sw = new StringWriter(); XmlSerializer xmlConvoElement = Xml.newSerializer(); try { @@ -131,7 +130,7 @@ public class BluetoothMapConvoListing { 2); Log.w(TAG, e); } - return sw.toString().getBytes("UTF-8"); + return sw.toString().getBytes(StandardCharsets.UTF_8); } public void sort() { diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java index 632338dab99..79faecb171f 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapConvoListingElement.java @@ -29,7 +29,6 @@ import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -219,17 +218,7 @@ public class BluetoothMapConvoListingElement /* Get a valid UTF-8 string of maximum 256 bytes */ private String getSummary() { if (mSummary != null) { - try { - return BluetoothMapUtils.truncateUtf8StringToString(mSummary, 256); - } catch (UnsupportedEncodingException e) { - ContentProfileErrorReportUtils.report( - BluetoothProfile.MAP, - BluetoothProtoEnums.BLUETOOTH_MAP_CONVO_LISTING_ELEMENT, - BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, - 1); - // This cannot happen on an Android platform - UTF-8 is mandatory - Log.e(TAG, "Missing UTF-8 support on platform", e); - } + return BluetoothMapUtils.truncateUtf8StringToString(mSummary, 256); } return null; } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java index 504d16f45c2..c1904bc5ade 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java @@ -30,7 +30,7 @@ import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Locale; @@ -50,9 +50,9 @@ public class BluetoothMapFolderElement implements Comparable(); } @@ -260,7 +260,7 @@ public class BluetoothMapFolderElement implements Comparable") - .getBytes("UTF-8"); + .getBytes(StandardCharsets.UTF_8); } - return sw.toString().getBytes("UTF-8"); + return sw.toString().getBytes(StandardCharsets.UTF_8); } public void sort() { diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java index 85b09515582..48e9ffc4976 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java @@ -33,6 +33,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; @@ -379,13 +380,12 @@ public class BluetoothMapSmsPdu { Log.v(TAG, "userDataMsgOffset:" + mUserDataMsgOffset); } - private void gsmWriteDate(ByteArrayOutputStream header, long time) - throws UnsupportedEncodingException { + private void gsmWriteDate(ByteArrayOutputStream header, long time) { SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmmss"); Date date = new Date(time); String timeStr = format.format(date); // Format to YYMMDDTHHMMSS UTC time Log.v(TAG, "Generated time string: " + timeStr); - byte[] timeChars = timeStr.getBytes("US-ASCII"); + byte[] timeChars = timeStr.getBytes(StandardCharsets.US_ASCII); for (int i = 0, n = timeStr.length(); i < n; i += 2) { header.write( diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java b/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java index 34636d9fa39..35424fc4b99 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapUtils.java @@ -186,17 +186,16 @@ public class BluetoothMapUtils { * characters as well as '-' separators * * @param valueStr a hexstring - NOTE: shall not contain any "0x" prefix. - * @throws UnsupportedEncodingException if "US-ASCII" charset is not supported, - * NullPointerException if a null pointer is passed to the function, NumberFormatException - * if the string contains invalid characters. + * @throws NullPointerException if a null pointer is passed to the function + * @throws NumberFormatException if the string contains invalid characters. */ - public static long getLongFromString(String valueStr) throws UnsupportedEncodingException { + public static long getLongFromString(String valueStr) { if (valueStr == null) { throw new NullPointerException(); } Log.v(TAG, "getLongFromString(): converting: " + valueStr); byte[] nibbles; - nibbles = valueStr.getBytes("US-ASCII"); + nibbles = valueStr.getBytes(StandardCharsets.US_ASCII); Log.v(TAG, " byte values: " + Arrays.toString(nibbles)); byte c; int count = 0; @@ -211,7 +210,11 @@ public class BluetoothMapUtils { } else if (c >= 'a' && c <= 'f') { c -= ('a' - 10); } else if (c <= ' ' || c == '-') { - Log.v(TAG, "Skipping c = '" + new String(new byte[] {(byte) c}, "US-ASCII") + "'"); + Log.v( + TAG, + "Skipping c = '" + + new String(new byte[] {(byte) c}, StandardCharsets.US_ASCII) + + "'"); continue; // Skip any whitespace and '-' (which is used for UUIDs) } else { throw new NumberFormatException("Invalid character:" + c); @@ -417,21 +420,11 @@ public class BluetoothMapUtils { * @param maxLength Max length of byte array returned including null termination * @return byte array containing valid utf8 characters with max length */ - public static byte[] truncateUtf8StringToBytearray(String utf8String, int maxLength) - throws UnsupportedEncodingException { + public static byte[] truncateUtf8StringToBytearray(String utf8String, int maxLength) { byte[] utf8Bytes = new byte[utf8String.length() + 1]; - try { - System.arraycopy(utf8String.getBytes("UTF-8"), 0, utf8Bytes, 0, utf8String.length()); - } catch (UnsupportedEncodingException e) { - ContentProfileErrorReportUtils.report( - BluetoothProfile.MAP, - BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, - BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, - 1); - Log.e(TAG, "truncateUtf8StringToBytearray: getBytes exception ", e); - throw e; - } + System.arraycopy( + utf8String.getBytes(StandardCharsets.UTF_8), 0, utf8Bytes, 0, utf8String.length()); if (utf8Bytes.length > maxLength) { /* if 'continuation' byte is in place 200, @@ -462,8 +455,7 @@ public class BluetoothMapUtils { * @param maxBytesLength Max length in bytes of the returned string * @return A valid truncated utf-8 string */ - public static String truncateUtf8StringToString(String utf8InString, int maxBytesLength) - throws UnsupportedEncodingException { + public static String truncateUtf8StringToString(String utf8InString, int maxBytesLength) { Charset charset = StandardCharsets.UTF_8; final byte[] utf8InBytes = utf8InString.getBytes(charset); if (utf8InBytes.length <= maxBytesLength) { @@ -569,17 +561,7 @@ public class BluetoothMapUtils { */ public static byte[] quotedPrintableToUtf8(String text, String charset) { byte[] output = new byte[text.length()]; // We allocate for the worst case memory need - byte[] input = null; - try { - input = text.getBytes("US-ASCII"); - } catch (UnsupportedEncodingException e) { - ContentProfileErrorReportUtils.report( - BluetoothProfile.MAP, - BluetoothProtoEnums.BLUETOOTH_MAP_UTILS, - BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, - 5); - /* This cannot happen as "US-ASCII" is supported for all Java implementations */ - } + byte[] input = text.getBytes(StandardCharsets.US_ASCII); if (input == null) { return "".getBytes(); diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java index 6d8cb70665b..6e5a556f3e6 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessage.java @@ -27,7 +27,7 @@ import com.android.internal.annotations.VisibleForTesting; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @@ -391,21 +391,11 @@ public abstract class BluetoothMapbMessage { * @return the next line of text, or null at end of file, or if UTF-8 is not supported. */ public String getLine() { - try { - byte[] line = getLineAsBytes(); - if (line.length == 0) { - return null; - } else { - return new String(line, "UTF-8"); - } - } catch (UnsupportedEncodingException e) { - ContentProfileErrorReportUtils.report( - BluetoothProfile.MAP, - BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE, - BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, - 1); - Log.w(TAG, e); + byte[] line = getLineAsBytes(); + if (line.length == 0) { return null; + } else { + return new String(line, StandardCharsets.UTF_8); } } @@ -755,7 +745,7 @@ public abstract class BluetoothMapbMessage { */ public abstract void parseMsgInit(); - public abstract byte[] encode() throws UnsupportedEncodingException; + public abstract byte[] encode(); public void setStatus(boolean read) { if (read) { @@ -936,7 +926,7 @@ public abstract class BluetoothMapbMessage { return out; } - public byte[] encodeGeneric(List bodyFragments) throws UnsupportedEncodingException { + public byte[] encodeGeneric(List bodyFragments) { StringBuilder sb = new StringBuilder(256); byte[] msgStart, msgEnd; sb.append("BEGIN:BMSG").append("\r\n"); @@ -986,14 +976,14 @@ public abstract class BluetoothMapbMessage { sb.append("LENGTH:").append(length).append("\r\n"); // Extract the initial part of the bMessage string - msgStart = sb.toString().getBytes("UTF-8"); + msgStart = sb.toString().getBytes(StandardCharsets.UTF_8); sb = new StringBuilder(31); sb.append("END:BBODY").append("\r\n"); sb.append("END:BENV").append("\r\n"); sb.append("END:BMSG").append("\r\n"); - msgEnd = sb.toString().getBytes("UTF-8"); + msgEnd = sb.toString().getBytes(StandardCharsets.UTF_8); try { @@ -1002,13 +992,13 @@ public abstract class BluetoothMapbMessage { stream.write(msgStart); for (byte[] fragment : bodyFragments) { - stream.write("BEGIN:MSG\r\n".getBytes("UTF-8")); + stream.write("BEGIN:MSG\r\n".getBytes(StandardCharsets.UTF_8)); stream.write(fragment); - stream.write("\r\nEND:MSG\r\n".getBytes("UTF-8")); + stream.write("\r\nEND:MSG\r\n".getBytes(StandardCharsets.UTF_8)); } stream.write(msgEnd); - Log.v(TAG, stream.toString("UTF-8")); + Log.v(TAG, stream.toString(StandardCharsets.UTF_8)); return stream.toByteArray(); } catch (IOException e) { ContentProfileErrorReportUtils.report( diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageEmail.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageEmail.java index 3ba2c881a21..3142ebbbabc 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageEmail.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageEmail.java @@ -21,8 +21,9 @@ import android.util.Log; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.List; // Next tag value for ContentProfileErrorReportUtils.report(): 1 public class BluetoothMapbMessageEmail extends BluetoothMapbMessage { @@ -57,8 +58,8 @@ public class BluetoothMapbMessageEmail extends BluetoothMapbMessage { } @Override - public byte[] encode() throws UnsupportedEncodingException { - ArrayList bodyFragments = new ArrayList(); + public byte[] encode() { + List bodyFragments = new ArrayList<>(); /* Store the messages in an ArrayList to be able to handle the different message types in a generic way. @@ -68,7 +69,7 @@ public class BluetoothMapbMessageEmail extends BluetoothMapbMessage { mEmailBody.replaceAll( "END:MSG", "/END\\:MSG"); // Replace any occurrences of END:MSG with \END:MSG - bodyFragments.add(tmpBody.getBytes("UTF-8")); + bodyFragments.add(tmpBody.getBytes(StandardCharsets.UTF_8)); } else { Log.e(TAG, "Email has no body - this should not be possible"); ContentProfileErrorReportUtils.report( diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java index 47bfa2deaa0..64cda05d81d 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageMime.java @@ -27,6 +27,7 @@ import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; @@ -53,7 +54,6 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { * jpeg data or the text.getBytes("utf-8") */ public String getDataAsString() { - String result = null; String charset = mCharsetName; // Figure out if we support the charset, else fall back to UTF-8, as this is what // the MAP specification suggest to use, and is compatible with US-ASCII. @@ -77,7 +77,7 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { } } try { - result = new String(mData, charset); + return new String(mData, charset); } catch (UnsupportedEncodingException e) { ContentProfileErrorReportUtils.report( BluetoothProfile.MAP, @@ -85,23 +85,11 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, 1); /* This cannot happen unless Charset.isSupported() is out of sync with String */ - try { - result = new String(mData, "UTF-8"); - } catch (UnsupportedEncodingException e2) { - ContentProfileErrorReportUtils.report( - BluetoothProfile.MAP, - BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE_MIME, - BluetoothStatsLog - .BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, - 2); - Log.e(TAG, "getDataAsString: " + e); - } + return new String(mData, StandardCharsets.UTF_8); } - return result; } - public void encode(StringBuilder sb, String boundaryTag, boolean last) - throws UnsupportedEncodingException { + public void encode(StringBuilder sb, String boundaryTag, boolean last) { sb.append("--").append(boundaryTag).append("\r\n"); if (mContentType != null) { sb.append("Content-Type: ").append(mContentType); @@ -127,8 +115,8 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { if (mContentType != null && (mContentType.toUpperCase().contains("TEXT") || mContentType.toUpperCase().contains("SMIL"))) { - String text = new String(mData, "UTF-8"); - if (text.getBytes().length == text.getBytes("UTF-8").length) { + String text = new String(mData, StandardCharsets.UTF_8); + if (text.getBytes().length == text.getBytes(StandardCharsets.UTF_8).length) { /* Add the header split empty line */ sb.append("Content-Transfer-Encoding: 8BIT\r\n\r\n"); } else { @@ -148,10 +136,10 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { } } - public void encodePlainText(StringBuilder sb) throws UnsupportedEncodingException { + public void encodePlainText(StringBuilder sb) { if (mContentType != null && mContentType.toUpperCase().contains("TEXT")) { - String text = new String(mData, "UTF-8"); - if (text.getBytes().length != text.getBytes("UTF-8").length) { + String text = new String(mData, StandardCharsets.UTF_8); + if (text.getBytes().length != text.getBytes(StandardCharsets.UTF_8).length) { text = BluetoothMapUtils.encodeQuotedPrintable(mData); } sb.append(text).append("\r\n"); @@ -420,7 +408,7 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { sb.append("\r\n"); } - public void encodeHeaders(StringBuilder sb) throws UnsupportedEncodingException { + public void encodeHeaders(StringBuilder sb) { /* TODO: From RFC-4356 - about the RFC-(2)822 headers: * "Current Internet Message format requires that only 7-bit US-ASCII * characters be present in headers. Non-7-bit characters in an address @@ -522,7 +510,7 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { * */ /** Encode the bMessage as a Mime message(MMS/IM) */ - public byte[] encodeMime() throws UnsupportedEncodingException { + public byte[] encodeMime() { ArrayList bodyFragments = new ArrayList(); StringBuilder sb = new StringBuilder(); int count = 0; @@ -551,7 +539,7 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { if (mimeBody != null) { // Replace any occurrences of END:MSG with \END:MSG String tmpBody = mimeBody.replaceAll("END:MSG", "/END\\:MSG"); - bodyFragments.add(tmpBody.getBytes("UTF-8")); + bodyFragments.add(tmpBody.getBytes(StandardCharsets.UTF_8)); } else { bodyFragments.add(new byte[0]); } @@ -751,19 +739,8 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { return BluetoothMapUtils.quotedPrintableToUtf8(body, charset); } else { // TODO: handle other encoding types? - here we simply store the string data as bytes - try { - - return body.getBytes("UTF-8"); - } catch (UnsupportedEncodingException e) { - ContentProfileErrorReportUtils.report( - BluetoothProfile.MAP, - BluetoothProtoEnums.BLUETOOTH_MAP_BMESSAGE_MIME, - BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, - 6); - // This will never happen, as UTF-8 is mandatory on Android platforms - } + return body.getBytes(StandardCharsets.UTF_8); } - return null; } private void parseMime(String message) { @@ -842,7 +819,7 @@ public class BluetoothMapbMessageMime extends BluetoothMapbMessage { } @Override - public byte[] encode() throws UnsupportedEncodingException { + public byte[] encode() { return encodeMime(); } } diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java index 48add7a2e78..80fb7cdc35c 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java @@ -20,7 +20,7 @@ import com.android.bluetooth.DeviceWorkArounds; import com.android.bluetooth.map.BluetoothMapSmsPdu.SmsPdu; import com.android.bluetooth.map.BluetoothMapUtils.TYPE; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @@ -76,7 +76,7 @@ public class BluetoothMapbMessageSms extends BluetoothMapbMessage { } @Override - public byte[] encode() throws UnsupportedEncodingException { + public byte[] encode() { List bodyFragments = new ArrayList<>(); /* Store the messages in an ArrayList to be able to handle the different message types in @@ -107,12 +107,13 @@ public class BluetoothMapbMessageSms extends BluetoothMapbMessage { while ((tmpBody.charAt(tmpBody.length() - trailingLF - 1)) == '\n') trailingLF++; tmpBody = tmpBody.substring(0, (tmpBody.length() - trailingLF)); } - bodyFragments.add(tmpBody.getBytes("UTF-8")); + bodyFragments.add(tmpBody.getBytes(StandardCharsets.UTF_8)); } else if (mSmsBodyPdus != null && mSmsBodyPdus.size() > 0) { for (SmsPdu pdu : mSmsBodyPdus) { // This cannot(must not) contain END:MSG bodyFragments.add( - encodeBinary(pdu.getData(), pdu.getScAddress()).getBytes("UTF-8")); + encodeBinary(pdu.getData(), pdu.getScAddress()) + .getBytes(StandardCharsets.UTF_8)); } } else { bodyFragments.add(new byte[0]); // An empty message - no text diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java index ea61bee0795..d0c0d660a33 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java @@ -47,7 +47,7 @@ import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; @@ -157,19 +157,10 @@ public class BluetoothOppReceiveFileInfo { Log.i(Constants.TAG, " File Name Length :" + filename.length()); Log.i(Constants.TAG, " File Name Length in Bytes:" + filename.getBytes().length); - try { - byte[] oldfilename = filename.getBytes("UTF-8"); - byte[] newfilename = new byte[OPP_LENGTH_OF_FILE_NAME]; - System.arraycopy(oldfilename, 0, newfilename, 0, OPP_LENGTH_OF_FILE_NAME); - filename = new String(newfilename, "UTF-8"); - } catch (UnsupportedEncodingException e) { - ContentProfileErrorReportUtils.report( - BluetoothProfile.OPP, - BluetoothProtoEnums.BLUETOOTH_OPP_RECEIVE_FILE_INFO, - BluetoothStatsLog.BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED__TYPE__EXCEPTION, - 0); - Log.e(Constants.TAG, "Exception: " + e); - } + byte[] oldfilename = filename.getBytes(StandardCharsets.UTF_8); + byte[] newfilename = new byte[OPP_LENGTH_OF_FILE_NAME]; + System.arraycopy(oldfilename, 0, newfilename, 0, OPP_LENGTH_OF_FILE_NAME); + filename = new String(newfilename, StandardCharsets.UTF_8); Log.d(Constants.TAG, "File name is too long. Name is truncated as: " + filename); } -- GitLab From dc784cdd7703a12769fc0ec3b0138155a7b1474d Mon Sep 17 00:00:00 2001 From: William Escande Date: Tue, 11 Jun 2024 01:04:39 -0700 Subject: [PATCH 0055/1446] ErrorProne: Enforce & fix StringCaseLocaleUsage See https://errorprone.info/bugpattern/StringCaseLocaleUsage Bug: 344658662 Test: m BluetoothInstrumentationTests Flag: Exempt Build and test only Change-Id: I802f6d0cbce11796e9e857cfb05701ec7d36aced --- android/app/Android.bp | 1 + .../android/bluetooth/DeviceWorkArounds.java | 4 ++- .../avrcpcontroller/bip/BipEncoding.java | 12 +++++---- .../bip/BipTransformation.java | 4 ++- .../bluetooth/btservice/AdapterService.java | 3 ++- .../bluetooth/map/BluetoothMapContent.java | 9 ++++--- .../map/BluetoothMapContentObserver.java | 5 ++-- .../map/BluetoothMapFolderElement.java | 4 ++- .../bluetooth/map/BluetoothMapUtils.java | 4 ++- .../bluetooth/map/BluetoothMapbMessage.java | 8 +++--- .../map/BluetoothMapbMessageMime.java | 27 ++++++++++--------- .../opp/BluetoothOppObexServerSession.java | 5 ++-- .../pbap/BluetoothPbapObexServer.java | 8 +++--- android/app/tests/unit/Android.bp | 1 + .../opp/BluetoothOppNotificationTest.java | 10 ++++--- framework/Android.bp | 1 + service/Android.bp | 1 + 17 files changed, 67 insertions(+), 40 deletions(-) diff --git a/android/app/Android.bp b/android/app/Android.bp index f2f0a70927c..b8854fcd078 100644 --- a/android/app/Android.bp +++ b/android/app/Android.bp @@ -332,6 +332,7 @@ android_app { "-Xep:NonApiType:ERROR", "-Xep:NonCanonicalType:ERROR", "-Xep:ReturnAtTheEndOfVoidFunction:ERROR", + "-Xep:StringCaseLocaleUsage:ERROR", "-Xep:StringCharset:ERROR", "-Xep:UnusedMethod:ERROR", "-Xep:UnusedVariable:ERROR", diff --git a/android/app/src/com/android/bluetooth/DeviceWorkArounds.java b/android/app/src/com/android/bluetooth/DeviceWorkArounds.java index 67f8e0134cd..ed7e816d950 100644 --- a/android/app/src/com/android/bluetooth/DeviceWorkArounds.java +++ b/android/app/src/com/android/bluetooth/DeviceWorkArounds.java @@ -16,6 +16,8 @@ package com.android.bluetooth; +import com.google.common.base.Ascii; + public final class DeviceWorkArounds { public static final String PCM_CARKIT = "9C:DF:03"; public static final String FORD_SYNC_CARKIT = "00:1E:AE"; @@ -25,6 +27,6 @@ public final class DeviceWorkArounds { public static final String MERCEDES_BENZ_CARKIT = "00:26:e8"; public static boolean addressStartsWith(String bdAddr, String carkitAddr) { - return bdAddr.toLowerCase().startsWith(carkitAddr.toLowerCase()); + return Ascii.toLowerCase(bdAddr).startsWith(Ascii.toLowerCase(carkitAddr)); } } diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java index 4de8caf7edb..72d38191670 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java @@ -18,6 +18,8 @@ package com.android.bluetooth.avrcpcontroller; import android.util.SparseArray; +import com.google.common.base.Ascii; + import java.util.HashMap; /** @@ -83,12 +85,12 @@ public class BipEncoding { if (encoding == null) { throw new ParseException("Encoding input invalid"); } - encoding = encoding.trim(); - mType = determineEncoding(encoding.toUpperCase()); + encoding = Ascii.toUpperCase(encoding.trim()); + mType = determineEncoding(encoding); String proprietaryEncodingId = null; if (mType == USR_XXX) { - proprietaryEncodingId = encoding.substring(4).toUpperCase(); + proprietaryEncodingId = encoding.substring(4); } mProprietaryEncodingId = proprietaryEncodingId; @@ -102,7 +104,7 @@ public class BipEncoding { * Create an encoding object based on one of the constants for the available formats * * @param encoding A constant representing an available encoding - * @param proprietaryId A string representing the Id of a propreitary encoding. Only used if the + * @param proprietaryId A string representing the Id of a proprietary encoding. Only used if the * encoding type is BipEncoding.USR_XXX */ public BipEncoding(int encoding, String proprietaryId) { @@ -117,7 +119,7 @@ public class BipEncoding { throw new IllegalArgumentException( "Received invalid user defined encoding id '" + proprietaryId + "'"); } - proprietaryEncodingId = proprietaryId.toUpperCase(); + proprietaryEncodingId = Ascii.toUpperCase(proprietaryId); } mProprietaryEncodingId = proprietaryEncodingId; } diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java index bb2e7ecb496..0d0963cf6f0 100644 --- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java +++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java @@ -18,6 +18,8 @@ package com.android.bluetooth.avrcpcontroller; import android.util.Log; +import com.google.common.base.Ascii; + import java.util.HashSet; /** @@ -51,7 +53,7 @@ public class BipTransformation { public BipTransformation(String transformations) { if (transformations == null) return; - transformations = transformations.trim().toLowerCase(); + transformations = Ascii.toLowerCase(transformations.trim()); String[] tokens = transformations.split(" "); for (String token : tokens) { switch (token) { diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java index 77a5a46a9bc..2e39c10ac1a 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java @@ -157,6 +157,7 @@ import com.android.modules.utils.BytesMatcher; import libcore.util.SneakyThrow; +import com.google.common.base.Ascii; import com.google.protobuf.InvalidProtocolBufferException; import java.io.FileDescriptor; @@ -4794,7 +4795,7 @@ public class AdapterService extends Service { public String getIdentityAddress(String address) { BluetoothDevice device = - BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address.toUpperCase()); + BluetoothAdapter.getDefaultAdapter().getRemoteDevice(Ascii.toUpperCase(address)); DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); if (deviceProp != null && deviceProp.getIdentityAddress() != null) { return deviceProp.getIdentityAddress(); diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java b/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java index 205c896533f..e712d5e1437 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapContent.java @@ -51,6 +51,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.google.android.mms.pdu.CharacterSets; import com.google.android.mms.pdu.PduHeaders; +import com.google.common.base.Ascii; import java.io.ByteArrayOutputStream; import java.io.Closeable; @@ -148,7 +149,7 @@ public class BluetoothMapContent { Mms.MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND); - public static final String INSERT_ADDRES_TOKEN = "insert-address-token"; + private static final String INSERT_ADDRESS_TOKEN = "insert-address-token"; private final Context mContext; private final ContentResolver mResolver; @@ -1480,7 +1481,7 @@ public class BluetoothMapContent { if (c != null) { if (c.moveToFirst()) { addr = c.getString(colIndex); - if (INSERT_ADDRES_TOKEN.equals(addr)) { + if (INSERT_ADDRESS_TOKEN.equals(addr)) { addr = ""; } } @@ -3755,7 +3756,7 @@ public class BluetoothMapContent { if (c.moveToFirst()) { do { String address = c.getString(c.getColumnIndex(Mms.Addr.ADDRESS)); - if (address.equals(INSERT_ADDRES_TOKEN)) { + if (address.equals(INSERT_ADDRESS_TOKEN)) { continue; } Integer type = c.getInt(c.getColumnIndex(Mms.Addr.TYPE)); @@ -3897,7 +3898,7 @@ public class BluetoothMapContent { // according to spec, "charset" should not be set. However, if the attachment // is replaced with a text string, the bMessage now contains text and should // have charset set to UTF-8 according to spec. - if (!part.mContentType.toUpperCase().contains("TEXT") + if (!Ascii.toUpperCase(part.mContentType).contains("TEXT") && !message.getIncludeAttachments()) { StringBuilder sb = new StringBuilder(); part.encodePlainText(sb); diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java index 2f8c8c941f7..bad8f17c4cd 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java @@ -66,6 +66,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.obex.ResponseCodes; import com.google.android.mms.pdu.PduHeaders; +import com.google.common.base.Ascii; import org.xmlpull.v1.XmlSerializer; @@ -3549,7 +3550,7 @@ public class BluetoothMapContentObserver { count++; values.clear(); if (part.mContentType != null - && part.mContentType.toUpperCase().contains("TEXT")) { + && Ascii.toUpperCase(part.mContentType).contains("TEXT")) { values.put(Mms.Part.CONTENT_TYPE, "text/plain"); values.put(Mms.Part.CHARSET, 106); if (part.mPartName != null) { @@ -3589,7 +3590,7 @@ public class BluetoothMapContentObserver { Log.v(TAG, "Added TEXT part"); } else if (part.mContentType != null - && part.mContentType.toUpperCase().contains("SMIL")) { + && Ascii.toUpperCase(part.mContentType).contains("SMIL")) { values.put(Mms.Part.SEQ, -1); values.put(Mms.Part.CONTENT_TYPE, "application/smil"); if (part.mContentId != null) { diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java b/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java index c1904bc5ade..e026ccd6902 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapFolderElement.java @@ -23,6 +23,8 @@ import com.android.bluetooth.BluetoothStatsLog; import com.android.bluetooth.Utils; import com.android.bluetooth.content_profiles.ContentProfileErrorReportUtils; +import com.google.common.base.Ascii; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -257,7 +259,7 @@ public class BluetoothMapFolderElement implements Comparable savedPosList = new ArrayList<>(); List selectedNameList = new ArrayList(); if (appParamValue.searchValue != null) { - compareValue = appParamValue.searchValue.trim().toLowerCase(); + compareValue = Ascii.toLowerCase(appParamValue.searchValue.trim()); } for (int pos = 0; pos < listSize; pos++) { @@ -1021,8 +1023,8 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { if (appParamValue.searchValue != null) { if (appParamValue.searchValue.isEmpty() - || ((currentValue.toLowerCase()) - .startsWith(compareValue.toLowerCase()))) { + || Ascii.toLowerCase(currentValue) + .startsWith(Ascii.toLowerCase(compareValue))) { selectedNameList.add(currentValue); savedPosList.add(pos); } diff --git a/android/app/tests/unit/Android.bp b/android/app/tests/unit/Android.bp index a86c38099ff..c6ef53c1c72 100644 --- a/android/app/tests/unit/Android.bp +++ b/android/app/tests/unit/Android.bp @@ -72,6 +72,7 @@ java_defaults { "-Xep:NonApiType:ERROR", "-Xep:NonCanonicalType:ERROR", "-Xep:ReturnAtTheEndOfVoidFunction:ERROR", + "-Xep:StringCaseLocaleUsage:ERROR", "-Xep:StringCharset:ERROR", "-Xep:UnnecessaryAssignment:ERROR", "-Xep:UnnecessaryAsync:ERROR", diff --git a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppNotificationTest.java b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppNotificationTest.java index 9cdbf70e3b4..81bf6e55964 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppNotificationTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/opp/BluetoothOppNotificationTest.java @@ -46,6 +46,8 @@ import com.android.bluetooth.BluetoothMethodProxy; import com.android.bluetooth.R; import com.android.bluetooth.TestUtils; +import com.google.common.base.Ascii; + import org.junit.After; import org.junit.Before; import org.junit.Ignore; @@ -430,13 +432,13 @@ public class BluetoothOppNotificationTest { UiObject2 buttonOk = device.findObject(By.text(confirmString)); // In AOSP, all actions' titles are converted into upper case if (buttonOk == null) { - buttonOk = device.findObject(By.text(confirmString.toUpperCase())); + buttonOk = device.findObject(By.text(Ascii.toUpperCase(confirmString))); } UiObject2 buttonDecline = device.findObject(By.text(declineString)); // In AOSP, all actions' titles are converted into upper case if (buttonDecline == null) { - buttonDecline = device.findObject(By.text(declineString.toUpperCase())); + buttonDecline = device.findObject(By.text(Ascii.toUpperCase(declineString))); } assertThat(title).isNotNull(); @@ -454,8 +456,8 @@ public class BluetoothOppNotificationTest { assertThat(device.findObject(By.text(titleString))).isNull(); assertThat(device.findObject(By.text(confirmString))).isNull(); - assertThat(device.findObject(By.text(confirmString.toUpperCase()))).isNull(); + assertThat(device.findObject(By.text(Ascii.toUpperCase(confirmString)))).isNull(); assertThat(device.findObject(By.text(declineString))).isNull(); - assertThat(device.findObject(By.text(declineString.toUpperCase()))).isNull(); + assertThat(device.findObject(By.text(Ascii.toUpperCase(declineString)))).isNull(); } } diff --git a/framework/Android.bp b/framework/Android.bp index b6a4717c775..9452f92efc5 100644 --- a/framework/Android.bp +++ b/framework/Android.bp @@ -105,6 +105,7 @@ java_sdk_library { "-Xep:NonApiType:ERROR", "-Xep:NonCanonicalType:ERROR", "-Xep:ReturnAtTheEndOfVoidFunction:ERROR", + "-Xep:StringCaseLocaleUsage:ERROR", "-Xep:StringCharset:ERROR", "-Xep:UnnecessaryAssignment:ERROR", "-Xep:UnnecessaryAsync:ERROR", diff --git a/service/Android.bp b/service/Android.bp index 389ca316c8d..12019d0be79 100644 --- a/service/Android.bp +++ b/service/Android.bp @@ -39,6 +39,7 @@ java_defaults { "-Xep:NonCanonicalType:ERROR", "-Xep:ReferenceEquality:ERROR", "-Xep:ReturnAtTheEndOfVoidFunction:ERROR", + "-Xep:StringCaseLocaleUsage:ERROR", "-Xep:StringCharset:ERROR", "-Xep:UnnecessaryAssignment:ERROR", "-Xep:UnnecessaryAsync:ERROR", -- GitLab From d7e497e044c9ebc0cddf5c3e97825446c48904a1 Mon Sep 17 00:00:00 2001 From: William Escande Date: Tue, 11 Jun 2024 01:40:24 -0700 Subject: [PATCH 0056/1446] ErrorProne: Partial fix SynchronizeOnNonFinalField See https://errorprone.info/bugpattern/SynchronizeOnNonFinalField Bug: 344658662 Test: m BluetoothInstrumentationTests Flag: Exempt Build and test only Change-Id: I435ce1d6d0fdbc3064b2767ec7cbebe6e37cc23f --- .../bluetooth/le_scan/PeriodicScanManager.java | 5 +++-- .../android/bluetooth/mapclient/MceStateMachine.java | 9 +++++++-- .../bluetooth/mcp/MediaControlGattService.java | 11 ++++++----- .../bluetooth/pbapclient/PbapClientService.java | 2 +- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java index 006fd6004ae..f2af13135a4 100644 --- a/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java +++ b/android/app/src/com/android/bluetooth/le_scan/PeriodicScanManager.java @@ -43,8 +43,9 @@ public class PeriodicScanManager { private final BluetoothAdapter mAdapter; private final PeriodicScanNativeInterface mNativeInterface; - Map mSyncs = new ConcurrentHashMap<>(); - Map mSyncTransfers = Collections.synchronizedMap(new HashMap<>()); + private final Map mSyncs = new ConcurrentHashMap<>(); + private final Map mSyncTransfers = + Collections.synchronizedMap(new HashMap<>()); static int sTempRegistrationId = -1; /** Constructor of {@link PeriodicScanManager}. */ diff --git a/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java b/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java index 07ce3ee71d2..173476337c0 100644 --- a/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java +++ b/android/app/src/com/android/bluetooth/mapclient/MceStateMachine.java @@ -56,6 +56,7 @@ import com.android.bluetooth.btservice.MetricsLogger; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.flags.Flags; import com.android.bluetooth.map.BluetoothMapbMessageMime; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.State; import com.android.internal.util.StateMachine; @@ -148,6 +149,10 @@ class MceStateMachine extends StateMachine { private HashMap mSentReceiptRequested = new HashMap<>(MAX_MESSAGES); private HashMap mDeliveryReceiptRequested = new HashMap<>(MAX_MESSAGES); + + private final Object mLock = new Object(); + + @GuardedBy("mLock") private Bmessage.Type mDefaultMessageType = Bmessage.Type.SMS_CDMA; // The amount of time for MCE to search for remote device's own phone number before: @@ -472,7 +477,7 @@ class MceStateMachine extends StateMachine { } Bmessage.Type getDefaultMessageType() { - synchronized (mDefaultMessageType) { + synchronized (mLock) { if (Utils.isPtsTestMode()) { int messageType = SystemProperties.getInt(SEND_MESSAGE_TYPE, -1); if (messageType > 0 && messageType < Bmessage.Type.values().length) { @@ -485,7 +490,7 @@ class MceStateMachine extends StateMachine { void setDefaultMessageType(SdpMasRecord sdpMasRecord) { int supportedMessageTypes = sdpMasRecord.getSupportedMessageTypes(); - synchronized (mDefaultMessageType) { + synchronized (mLock) { if ((supportedMessageTypes & SdpMasRecord.MessageType.MMS) > 0) { mDefaultMessageType = Bmessage.Type.MMS; } else if ((supportedMessageTypes & SdpMasRecord.MessageType.SMS_CDMA) > 0) { diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java index d5d457a8044..8ee75e0f00c 100644 --- a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java +++ b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java @@ -139,16 +139,17 @@ public class MediaControlGattService implements MediaControlGattServiceInterface | Request.SupportedOpcodes.PREVIOUS_TRACK; private final int mCcid; - private Map> mCccDescriptorValues = new HashMap<>(); + private final Map> mCccDescriptorValues = new HashMap<>(); private long mFeatures; private Context mContext; private MediaControlServiceCallbacks mCallbacks; private BluetoothGattServerProxy mBluetoothGattServer; private BluetoothGattService mGattService = null; - private Handler mHandler = new Handler(Looper.getMainLooper()); - private Map mCharacteristics = new HashMap<>(); + private final Handler mHandler = new Handler(Looper.getMainLooper()); + private final Map mCharacteristics = new HashMap<>(); private MediaState mCurrentMediaState = MediaState.INACTIVE; - private Map> mPendingGattOperations = new HashMap<>(); + private final Map> mPendingGattOperations = + new HashMap<>(); private McpService mMcpService; private LeAudioService mLeAudioService; private AdapterService mAdapterService; @@ -1584,7 +1585,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface SearchRequest request, SearchRequest.Results resultStatus, long resultObjectId) { Log.d(TAG, "setSearchRequestResult"); - // TODO: There is no Object Trasfer Service implementation. + // TODO: There is no Object Transfer Service implementation. BluetoothGattCharacteristic characteristic = mCharacteristics.get(CharId.SEARCH_CONTROL_POINT); characteristic.setValue(new byte[] {SEARCH_CONTROL_POINT_RESULT_FAILURE}); diff --git a/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java b/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java index d3a8665495c..7938f77bfc3 100644 --- a/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java +++ b/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java @@ -68,7 +68,7 @@ public class PbapClientService extends ProfileService { private static final int MAXIMUM_DEVICES = 10; @VisibleForTesting - Map mPbapClientStateMachineMap = + final Map mPbapClientStateMachineMap = new ConcurrentHashMap<>(); private static PbapClientService sPbapClientService; -- GitLab From 69611e2883b6a54c46f99cec6f048c7dfa313ffa Mon Sep 17 00:00:00 2001 From: William Escande Date: Tue, 11 Jun 2024 02:03:30 -0700 Subject: [PATCH 0057/1446] ErrorProne: Enforce & fix NotJavadoc See https://errorprone.info/bugpattern/NotJavadoc Bug: 344658662 Test: m BluetoothInstrumentationTests Flag: Exempt Build and test only Change-Id: Ia9f98f67cac6ce7fb75204a869fed82a2e492bae --- android/app/Android.bp | 1 + .../android/bluetooth/audio_util/MediaPlayerList.java | 10 ++-------- .../src/com/android/bluetooth/hfp/HeadsetService.java | 2 +- .../bluetooth/map/BluetoothMapContentObserver.java | 2 +- .../com/android/bluetooth/map/BluetoothMapSmsPdu.java | 2 +- .../android/bluetooth/opp/BluetoothOppTransfer.java | 2 +- .../bluetooth/pbap/BluetoothPbapObexServer.java | 2 +- android/app/tests/unit/Android.bp | 1 + framework/Android.bp | 1 + service/Android.bp | 1 + 10 files changed, 11 insertions(+), 13 deletions(-) diff --git a/android/app/Android.bp b/android/app/Android.bp index b8854fcd078..23d9ba4861d 100644 --- a/android/app/Android.bp +++ b/android/app/Android.bp @@ -331,6 +331,7 @@ android_app { "-Xep:MockNotUsedInProduction:ERROR", "-Xep:NonApiType:ERROR", "-Xep:NonCanonicalType:ERROR", + "-Xep:NotJavadoc:ERROR", "-Xep:ReturnAtTheEndOfVoidFunction:ERROR", "-Xep:StringCaseLocaleUsage:ERROR", "-Xep:StringCharset:ERROR", diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java index 4f2274ee2d0..e08e3c82444 100644 --- a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java +++ b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java @@ -377,7 +377,7 @@ public class MediaPlayerList { sendFolderUpdate(false, true, false); } } else { - /** M: Fix PTS AVRCP/TG/MCN/CB/BI-02-C fail @{ */ + // Fix PTS AVRCP/TG/MCN/CB/BI-02-C if (Utils.isPtsTestMode()) { d("PTS test mode: getPlayerRoot"); BrowsedPlayerWrapper wrapper = mBrowsablePlayers.get(BLUETOOTH_PLAYER_ID + 1); @@ -394,9 +394,6 @@ public class MediaPlayerList { }); return; } - /** - * @} - */ cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", mBrowsablePlayers.size()); } } @@ -661,7 +658,7 @@ public class MediaPlayerList { Log.d(TAG, "getFolderItems(): playerId=" + playerId + ", mediaId=" + mediaId); if (!Flags.browsingRefactor() && Utils.isPtsTestMode()) { - /** M: Fix PTS AVRCP/TG/MCN/CB/BI-02-C fail @{ */ + // Fix PTS AVRCP/TG/MCN/CB/BI-02-C d("PTS test mode: getFolderItems"); BrowsedPlayerWrapper wrapper = mBrowsablePlayers.get(BLUETOOTH_PLAYER_ID + 1); String itemId = mediaId; @@ -679,9 +676,6 @@ public class MediaPlayerList { cb.run(mediaId, results); }); return; - /** - * @} - */ } // The device is requesting the content of the root folder. This folder contains a list of diff --git a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java index 3b3c89fad24..e8ad531c7c9 100644 --- a/android/app/src/com/android/bluetooth/hfp/HeadsetService.java +++ b/android/app/src/com/android/bluetooth/hfp/HeadsetService.java @@ -2055,7 +2055,7 @@ public class HeadsetService extends ProfileService { if (currentPolicy != null && currentPolicy.getActiveDevicePolicyAfterConnection() == BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) { - /** + /* * If the active device was set because of the pick up audio policy and the * connecting policy is NOT_ALLOWED, then after the call is terminated, we must * de-activate this device. If there is a fallback mechanism, we should follow diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java index bad8f17c4cd..f70903f1bed 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java @@ -3453,7 +3453,7 @@ public class BluetoothMapContentObserver { } private long pushMmsToFolder(int folder, String[] toAddress, BluetoothMapbMessageMime msg) { - /** + /* * strategy: 1) parse msg into parts + header 2) create thread id (abuse the ease of adding * an SMS to get id for thread) 3) push parts into content://mms/parts/ table 3) */ diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java index 48e9ffc4976..5c3130ece70 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java @@ -826,7 +826,7 @@ public class BluetoothMapSmsPdu { private static int[] getTableFromByteArray(byte[] data) { ByteArrayInputStream inStream = new ByteArrayInputStream(data); - /** tableValue[0]: languageTable tableValue[1]: languageShiftTable */ + /* tableValue[0]: languageTable tableValue[1]: languageShiftTable */ int[] tableValue = new int[2]; while (inStream.available() > 0) { int id = inStream.read(); diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java index 51e3ee92526..8f1e25d3c63 100644 --- a/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java +++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppTransfer.java @@ -635,7 +635,7 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch * mSession instance. */ if (mSession == null) { - /** set current share as error */ + /* set current share as error */ Log.e(TAG, "Unexpected error happened !"); ContentProfileErrorReportUtils.report( BluetoothProfile.OPP, diff --git a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java index c7fab2fc0d0..07a2e49744a 100644 --- a/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java +++ b/android/app/src/com/android/bluetooth/pbap/BluetoothPbapObexServer.java @@ -1509,7 +1509,7 @@ public class BluetoothPbapObexServer extends ServerRequestHandler { int requestSize = pbSize >= appParamValue.maxListCount ? appParamValue.maxListCount : pbSize; - /** + /* * startIndex (resp., lastIndex) corresponds to the index of the first (resp., last) vcard * entry in the phonebook object. PBAP v1.2.3: only pb starts indexing at 0.vcf (owner * card), the other phonebook objects (e.g., fav) start at 1.vcf. Additionally, the owner diff --git a/android/app/tests/unit/Android.bp b/android/app/tests/unit/Android.bp index c6ef53c1c72..a737efb565e 100644 --- a/android/app/tests/unit/Android.bp +++ b/android/app/tests/unit/Android.bp @@ -71,6 +71,7 @@ java_defaults { "-Xep:MockNotUsedInProduction:ERROR", "-Xep:NonApiType:ERROR", "-Xep:NonCanonicalType:ERROR", + "-Xep:NotJavadoc:ERROR", "-Xep:ReturnAtTheEndOfVoidFunction:ERROR", "-Xep:StringCaseLocaleUsage:ERROR", "-Xep:StringCharset:ERROR", diff --git a/framework/Android.bp b/framework/Android.bp index 9452f92efc5..1750cf32eac 100644 --- a/framework/Android.bp +++ b/framework/Android.bp @@ -104,6 +104,7 @@ java_sdk_library { "-Xep:MockNotUsedInProduction:ERROR", "-Xep:NonApiType:ERROR", "-Xep:NonCanonicalType:ERROR", + "-Xep:NotJavadoc:ERROR", "-Xep:ReturnAtTheEndOfVoidFunction:ERROR", "-Xep:StringCaseLocaleUsage:ERROR", "-Xep:StringCharset:ERROR", diff --git a/service/Android.bp b/service/Android.bp index 12019d0be79..7a4535aedd5 100644 --- a/service/Android.bp +++ b/service/Android.bp @@ -37,6 +37,7 @@ java_defaults { "-Xep:MockNotUsedInProduction:ERROR", "-Xep:NonApiType:ERROR", "-Xep:NonCanonicalType:ERROR", + "-Xep:NotJavadoc:ERROR", "-Xep:ReferenceEquality:ERROR", "-Xep:ReturnAtTheEndOfVoidFunction:ERROR", "-Xep:StringCaseLocaleUsage:ERROR", -- GitLab From 868c8ff8ff48809ccc5c299e279e091a234b7c6a Mon Sep 17 00:00:00 2001 From: PODISHETTY KUMAR Date: Tue, 18 Jun 2024 01:44:53 +0000 Subject: [PATCH 0058/1446] Revert "floss: Add IsLEAudioStable API" This reverts commit d454b17727f977f96691556e445dbf40f9754919. Reason for revert: Change-Id: I7942ad11b2f917ab3655a9aaddf47dfdb8047209 --- .../rust/linux/client/src/command_handler.rs | 4 -- system/gd/rust/linux/client/src/dbus_iface.rs | 5 -- .../rust/linux/service/src/iface_bluetooth.rs | 5 -- system/gd/rust/linux/stack/src/bluetooth.rs | 19 +------ system/gd/rust/topshim/src/btif.rs | 11 +---- system/gd/rust/topshim/src/sysprop.rs | 49 +------------------ system/gd/sysprops/sysprops_module.cc | 1 - 7 files changed, 3 insertions(+), 91 deletions(-) diff --git a/system/gd/rust/linux/client/src/command_handler.rs b/system/gd/rust/linux/client/src/command_handler.rs index 25ad024d8a5..e586eb51935 100644 --- a/system/gd/rust/linux/client/src/command_handler.rs +++ b/system/gd/rust/linux/client/src/command_handler.rs @@ -889,7 +889,6 @@ impl CommandHandler { uuids, wake_allowed, dual_mode_audio, - le_audio_stable, ) = { let ctx = self.lock_context(); let adapter = ctx.adapter_dbus.as_ref().unwrap(); @@ -909,7 +908,6 @@ impl CommandHandler { let uuids = adapter.get_remote_uuids(device.clone()); let wake_allowed = adapter.get_remote_wake_allowed(device.clone()); let dual_mode_audio = adapter.is_dual_mode_audio_sink_device(device.clone()); - let le_audio_stable = adapter.is_le_audio_stable(device.clone()); ( name, @@ -923,7 +921,6 @@ impl CommandHandler { uuids, wake_allowed, dual_mode_audio, - le_audio_stable, ) }; @@ -938,7 +935,6 @@ impl CommandHandler { print_info!("Bond State: {:?}", bonded); print_info!("Connection State: {}", connection_state); print_info!("Dual Mode Audio Device: {}", dual_mode_audio); - print_info!("Is LE Audio Stable: {}", le_audio_stable); print_info!( "Uuids: {}", DisplayList( diff --git a/system/gd/rust/linux/client/src/dbus_iface.rs b/system/gd/rust/linux/client/src/dbus_iface.rs index e3f070e70ac..6a2fe45b119 100644 --- a/system/gd/rust/linux/client/src/dbus_iface.rs +++ b/system/gd/rust/linux/client/src/dbus_iface.rs @@ -1036,11 +1036,6 @@ impl IBluetooth for BluetoothDBus { dbus_generated!() } - #[dbus_method("IsLEAudioStable")] - fn is_le_audio_stable(&self, device: BluetoothDevice) -> bool { - dbus_generated!() - } - #[dbus_method("GetDumpsys")] fn get_dumpsys(&self) -> String { dbus_generated!() diff --git a/system/gd/rust/linux/service/src/iface_bluetooth.rs b/system/gd/rust/linux/service/src/iface_bluetooth.rs index 3a1fc6530ef..063b3331344 100644 --- a/system/gd/rust/linux/service/src/iface_bluetooth.rs +++ b/system/gd/rust/linux/service/src/iface_bluetooth.rs @@ -771,11 +771,6 @@ impl IBluetooth for IBluetoothDBus { dbus_generated!() } - #[dbus_method("IsLEAudioStable", DBusLog::Disable)] - fn is_le_audio_stable(&self, device: BluetoothDevice) -> bool { - dbus_generated!() - } - #[dbus_method("GetDumpsys", DBusLog::Disable)] fn get_dumpsys(&self) -> String { dbus_generated!() diff --git a/system/gd/rust/linux/stack/src/bluetooth.rs b/system/gd/rust/linux/stack/src/bluetooth.rs index 69388bcd8d2..7898e8b57bc 100644 --- a/system/gd/rust/linux/stack/src/bluetooth.rs +++ b/system/gd/rust/linux/stack/src/bluetooth.rs @@ -17,7 +17,7 @@ use bt_topshim::{ }, profiles::sdp::{BtSdpRecord, Sdp, SdpCallbacks, SdpCallbacksDispatcher}, profiles::ProfileConnectionState, - sysprop, topstack, + topstack, }; use bt_utils::array_utils; @@ -265,9 +265,6 @@ pub trait IBluetooth { /// LE Audio sink roles). fn is_dual_mode_audio_sink_device(&self, device: BluetoothDevice) -> bool; - /// Returns whether the remote device is LE audio stable. - fn is_le_audio_stable(&self, device: BluetoothDevice) -> bool; - /// Gets diagnostic output. fn get_dumpsys(&self) -> String; } @@ -3007,20 +3004,6 @@ impl IBluetooth for Bluetooth { }) } - fn is_le_audio_stable(&self, device: BluetoothDevice) -> bool { - let model_name = - match self.get_remote_device_property(&device, &BtPropertyType::RemoteModelName) { - Some(BluetoothProperty::RemoteModelName(name)) => name, - _ => { - return false; - } - }; - - sysprop::get_string(sysprop::PropertyString::LeAudioAllowList) - .split(",") - .any(|model| model == model_name) - } - fn get_dumpsys(&self) -> String { NamedTempFile::new() .and_then(|file| { diff --git a/system/gd/rust/topshim/src/btif.rs b/system/gd/rust/topshim/src/btif.rs index 4b9e1b91277..0ce1be07d57 100644 --- a/system/gd/rust/topshim/src/btif.rs +++ b/system/gd/rust/topshim/src/btif.rs @@ -167,7 +167,7 @@ pub enum BtPropertyType { // Unimplemented: // BT_PROPERTY_REMOTE_ASHA_CAPABILITY, // BT_PROPERTY_REMOTE_ASHA_TRUNCATED_HISYNCID, - RemoteModelName = 0x17, + // BT_PROPERTY_REMOTE_MODEL_NUM, RemoteAddrType = 0x18, Unknown = 0xFE, @@ -583,7 +583,6 @@ pub enum BluetoothProperty { RemoteIsCoordinatedSetMember(bool), Appearance(u16), VendorProductInfo(BtVendorProductInfo), - RemoteModelName(String), RemoteAddrType(BtAddrType), RemoteDeviceTimestamp(), @@ -628,7 +627,6 @@ impl BluetoothProperty { BluetoothProperty::Appearance(_) => BtPropertyType::Appearance, BluetoothProperty::VendorProductInfo(_) => BtPropertyType::VendorProductInfo, BluetoothProperty::RemoteDeviceTimestamp() => BtPropertyType::RemoteDeviceTimestamp, - BluetoothProperty::RemoteModelName(_) => BtPropertyType::RemoteModelName, BluetoothProperty::RemoteAddrType(_) => BtPropertyType::RemoteAddrType, BluetoothProperty::Unknown() => BtPropertyType::Unknown, } @@ -660,7 +658,6 @@ impl BluetoothProperty { BluetoothProperty::RemoteIsCoordinatedSetMember(_) => mem::size_of::(), BluetoothProperty::Appearance(_) => mem::size_of::(), BluetoothProperty::VendorProductInfo(_) => mem::size_of::(), - BluetoothProperty::RemoteModelName(name) => name.len(), BluetoothProperty::RemoteAddrType(_) => mem::size_of::(), // TODO(abps) - Figure out sizes for these @@ -770,9 +767,6 @@ impl BluetoothProperty { }; data.copy_from_slice(&slice); } - BluetoothProperty::RemoteModelName(name) => { - data.copy_from_slice(name.as_bytes()); - } BluetoothProperty::RemoteAddrType(addr_type) => { data.copy_from_slice( &BtAddrType::to_u32(addr_type).unwrap_or_default().to_ne_bytes(), @@ -854,9 +848,6 @@ impl From for BluetoothProperty { let v = unsafe { (prop.val as *const BtVendorProductInfo).read_unaligned() }; BluetoothProperty::VendorProductInfo(BtVendorProductInfo::from(v)) } - BtPropertyType::RemoteModelName => { - BluetoothProperty::RemoteModelName(ascii_to_string(slice, len)) - } BtPropertyType::RemoteAddrType => BluetoothProperty::RemoteAddrType( BtAddrType::from_u32(u32_from_bytes(slice)).unwrap_or(BtAddrType::Unknown), ), diff --git a/system/gd/rust/topshim/src/sysprop.rs b/system/gd/rust/topshim/src/sysprop.rs index 00201347050..6dd00845678 100644 --- a/system/gd/rust/topshim/src/sysprop.rs +++ b/system/gd/rust/topshim/src/sysprop.rs @@ -3,9 +3,7 @@ use std::ffi::CString; use crate::bindings::root as bindings; -use crate::utils::{LTCheckedPtr, LTCheckedPtrMut}; - -const PROPERTY_VALUE_MAX: usize = 92; +use crate::utils::LTCheckedPtr; /// List of properties accessible to Rust. Add new ones here as they become /// necessary. @@ -96,48 +94,3 @@ pub fn get_bool(prop: PropertyBool) -> bool { // SAFETY: Calling C++ function with compatible types (null terminated string and bool) is safe. unsafe { bindings::osi_property_get_bool(key_cptr.into(), default_value) } } - -/// List of string properties accessible to Rust. Add new ones here as they become -/// necessary. -pub enum PropertyString { - // bluetooth.le_audio - LeAudioAllowList, -} - -impl Into<(CString, CString)> for PropertyString { - /// Convert the property into the property key name and a default value. - fn into(self) -> (CString, CString) { - let (key, default_value) = match self { - PropertyString::LeAudioAllowList => ("persist.bluetooth.leaudio.allow_list", ""), - }; - - ( - CString::new(key).expect("CString::new failed on sysprop key"), - CString::new(default_value).expect("CString::new failed on sysprop default_value"), - ) - } -} - -/// Get the string value for a system property. -pub fn get_string(prop: PropertyString) -> String { - let (key, default_value): (CString, CString) = prop.into(); - let key_cptr = LTCheckedPtr::from(&key); - let default_val_cptr = LTCheckedPtr::from(&default_value); - let mut dest = vec![0u8; PROPERTY_VALUE_MAX]; - let dest_cptr = LTCheckedPtrMut::from(&mut dest); - - // SAFETY: Calling C++ function with compatible types (null terminated strings) is safe. - let len = unsafe { - bindings::osi_property_get( - key_cptr.into(), - dest_cptr.cast_into::(), - default_val_cptr.into(), - ) - }; - if len <= 0 { - return "".to_string(); - } - - dest.resize(len as usize, b'\0'); - String::from_utf8(dest).expect("Found invalid UTF-8") -} diff --git a/system/gd/sysprops/sysprops_module.cc b/system/gd/sysprops/sysprops_module.cc index e0a2923a287..64b9e19fe07 100644 --- a/system/gd/sysprops/sysprops_module.cc +++ b/system/gd/sysprops/sysprops_module.cc @@ -122,7 +122,6 @@ void SyspropsModule::parse_config(std::string file_path) { // LE Audio "bluetooth.le_audio.enable_le_audio_only", "bluetooth.leaudio.dual_bidirection_swb.supported", - "persist.bluetooth.leaudio.allow_list", // SCO "bluetooth.sco.disable_enhanced_connection", "bluetooth.sco.swb_supported", -- GitLab From b479eedbe49702c3298d890bf582a6eb43ff6c70 Mon Sep 17 00:00:00 2001 From: Hyundo Moon Date: Mon, 17 Jun 2024 07:40:52 +0000 Subject: [PATCH 0059/1446] Fix typo BTA_GATTS_DELELTE_EVT It should be DELETE, not DELE'L'TE. Bug: 347632149 Test: m com.android.btservices Flag: EXEMPT, typo fix Change-Id: I1e9f7708c1fdc4d16b8bd07e7ca0469f1fe1828b --- system/bta/gatt/bta_gatts_act.cc | 2 +- system/bta/include/bta_gatt_api.h | 4 ++-- system/btif/src/btif_gatt_server.cc | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/system/bta/gatt/bta_gatts_act.cc b/system/bta/gatt/bta_gatts_act.cc index 2087de4a561..c7ea8a5b46e 100644 --- a/system/bta/gatt/bta_gatts_act.cc +++ b/system/bta/gatt/bta_gatts_act.cc @@ -310,7 +310,7 @@ void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB* p_srvc_cb, cb_data.srvc_oper.status = GATT_ERROR; } - if (p_rcb->p_cback) (*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data); + if (p_rcb->p_cback) (*p_rcb->p_cback)(BTA_GATTS_DELETE_EVT, &cb_data); } /******************************************************************************* diff --git a/system/bta/include/bta_gatt_api.h b/system/bta/include/bta_gatt_api.h index 4234f3cfec4..3d2dcfa72d4 100644 --- a/system/bta/include/bta_gatt_api.h +++ b/system/bta/include/bta_gatt_api.h @@ -283,7 +283,7 @@ typedef void(tBTA_GATTC_CBACK)(tBTA_GATTC_EVT event, tBTA_GATTC* p_data); #define BTA_GATTS_MTU_EVT GATTS_REQ_TYPE_MTU /* 6 */ #define BTA_GATTS_CONF_EVT GATTS_REQ_TYPE_CONF /* 7 */ #define BTA_GATTS_DEREG_EVT 8 -#define BTA_GATTS_DELELTE_EVT 11 +#define BTA_GATTS_DELETE_EVT 11 #define BTA_GATTS_STOP_EVT 13 #define BTA_GATTS_CONNECT_EVT 14 #define BTA_GATTS_DISCONNECT_EVT 15 @@ -308,7 +308,7 @@ inline std::string gatt_server_event_text(const tBTA_GATTS_EVT& event) { CASE_RETURN_TEXT(BTA_GATTS_MTU_EVT); CASE_RETURN_TEXT(BTA_GATTS_CONF_EVT); CASE_RETURN_TEXT(BTA_GATTS_DEREG_EVT); - CASE_RETURN_TEXT(BTA_GATTS_DELELTE_EVT); + CASE_RETURN_TEXT(BTA_GATTS_DELETE_EVT); CASE_RETURN_TEXT(BTA_GATTS_STOP_EVT); CASE_RETURN_TEXT(BTA_GATTS_CONNECT_EVT); CASE_RETURN_TEXT(BTA_GATTS_DISCONNECT_EVT); diff --git a/system/btif/src/btif_gatt_server.cc b/system/btif/src/btif_gatt_server.cc index c717652b328..092dac90ae0 100644 --- a/system/btif/src/btif_gatt_server.cc +++ b/system/btif/src/btif_gatt_server.cc @@ -161,7 +161,7 @@ static void btapp_gatts_handle_cback(uint16_t event, char* p_param) { p_data->srvc_oper.service_id); break; - case BTA_GATTS_DELELTE_EVT: + case BTA_GATTS_DELETE_EVT: HAL_CBACK(bt_gatt_callbacks, server->service_deleted_cb, p_data->srvc_oper.status, p_data->srvc_oper.server_if, p_data->srvc_oper.service_id); -- GitLab From 7d8e58e91d1e95d89da648ea0c272a8efa3cc4a1 Mon Sep 17 00:00:00 2001 From: Hsin-chen Chuang Date: Fri, 7 Jun 2024 11:29:47 +0800 Subject: [PATCH 0060/1446] floss client: Fix clippy warnings - warning: this `MutexGuard` is held across an `await` point - warning: this function has too many arguments (9/7) - warning: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - warning: use of a disallowed/placeholder name `foo` - warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do - warning: `format!` in `println!` args - warning: name `NONE` contains a capitalized acronym Bug: 343315863 Tag: #floss Test: mmm packages/modules/Bluetooth Test: ./build.py --target test Test: Deploy to Guybrush, played with btclient command Flag: EXEMPT, Floss-only changes Change-Id: Ieffd57244636ced2da057555c2de4a0ef8f4a839 --- system/gd/rust/linux/client/src/bt_gatt.rs | 4 +- system/gd/rust/linux/client/src/callbacks.rs | 45 ++++++++-------- .../rust/linux/client/src/command_handler.rs | 54 +++++++++---------- system/gd/rust/linux/client/src/dbus_iface.rs | 24 ++++++--- system/gd/rust/linux/client/src/main.rs | 2 +- .../dbus_projection/dbus_macros/src/lib.rs | 3 +- 6 files changed, 70 insertions(+), 62 deletions(-) diff --git a/system/gd/rust/linux/client/src/bt_gatt.rs b/system/gd/rust/linux/client/src/bt_gatt.rs index a8ac8df1c93..fbd8459d6c9 100644 --- a/system/gd/rust/linux/client/src/bt_gatt.rs +++ b/system/gd/rust/linux/client/src/bt_gatt.rs @@ -5,7 +5,7 @@ use bt_topshim::profiles::gatt::LePhy; #[derive(Debug, Copy, Clone)] pub enum AuthReq { // reference to system/stack/include/gatt_api.h - NONE = 0, + NoEnc = 0, EncNoMitm = 1, EncMitm = 2, SignedNoMitm = 3, @@ -38,7 +38,7 @@ impl GattClientContext { pub(crate) fn new() -> Self { GattClientContext { client_id: None, - auth_req: AuthReq::NONE, + auth_req: AuthReq::NoEnc, is_connect_direct: false, connect_transport: BtTransport::Le, connect_opportunistic: false, diff --git a/system/gd/rust/linux/client/src/callbacks.rs b/system/gd/rust/linux/client/src/callbacks.rs index 707e72d16c9..ea117b1e38d 100644 --- a/system/gd/rust/linux/client/src/callbacks.rs +++ b/system/gd/rust/linux/client/src/callbacks.rs @@ -176,15 +176,20 @@ impl IBluetoothCallback for BtCallback { } fn on_device_cleared(&mut self, remote_device: BluetoothDevice) { - match self.context.lock().unwrap().found_devices.remove(&remote_device.address.to_string()) + if self + .context + .lock() + .unwrap() + .found_devices + .remove(&remote_device.address.to_string()) + .is_some() { - Some(_) => print_info!( + print_info!( "Removed device: [{}: {:?}]", remote_device.address.to_string(), remote_device.name - ), - None => (), - }; + ); + } self.context.lock().unwrap().bonded_devices.remove(&remote_device.address.to_string()); } @@ -217,19 +222,16 @@ impl IBluetoothCallback for BtCallback { // Auto-confirm bonding attempts that were locally initiated. // Ignore all other bonding attempts. let bonding_device = context.lock().unwrap().bonding_attempt.as_ref().cloned(); - match bonding_device { - Some(bd) => { - if bd.address == rd.address { - context - .lock() - .unwrap() - .adapter_dbus - .as_ref() - .unwrap() - .set_pairing_confirmation(rd.clone(), true); - } + if let Some(bd) = bonding_device { + if bd.address == rd.address { + context + .lock() + .unwrap() + .adapter_dbus + .as_ref() + .unwrap() + .set_pairing_confirmation(rd.clone(), true); } - None => (), } })); } @@ -273,13 +275,10 @@ impl IBluetoothCallback for BtCallback { BtBondState::NotBonded | BtBondState::Bonded => { let bonding_attempt = self.context.lock().unwrap().bonding_attempt.as_ref().cloned(); - match bonding_attempt { - Some(bd) => { - if address == bd.address { - self.context.lock().unwrap().bonding_attempt = None; - } + if let Some(bd) = bonding_attempt { + if address == bd.address { + self.context.lock().unwrap().bonding_attempt = None; } - None => (), } } BtBondState::Bonding => (), diff --git a/system/gd/rust/linux/client/src/command_handler.rs b/system/gd/rust/linux/client/src/command_handler.rs index 1e0d27903d1..a3858812cbf 100644 --- a/system/gd/rust/linux/client/src/command_handler.rs +++ b/system/gd/rust/linux/client/src/command_handler.rs @@ -62,9 +62,9 @@ impl From for CommandError { type CommandResult = Result<(), CommandError>; -type CommandFunction = fn(&mut CommandHandler, &Vec) -> CommandResult; +type CommandFunction = fn(&mut CommandHandler, &[String]) -> CommandResult; -fn _noop(_handler: &mut CommandHandler, _args: &Vec) -> CommandResult { +fn _noop(_handler: &mut CommandHandler, _args: &[String]) -> CommandResult { // Used so we can add options with no direct function // e.g. help and quit Ok(()) @@ -406,7 +406,7 @@ fn build_commands() -> HashMap { // Use this to safely index an argument and conveniently return the error if the argument does not // exist. fn get_arg( - args: &Vec, + args: &[String], index: I, ) -> Result<&>::Output, CommandError> where @@ -422,7 +422,7 @@ impl CommandHandler { } /// Entry point for command and arguments - pub fn process_cmd_line(&mut self, command: &str, args: &Vec) -> bool { + pub fn process_cmd_line(&mut self, command: &str, args: &[String]) -> bool { // Ignore empty line match command { "" => false, @@ -463,7 +463,7 @@ impl CommandHandler { .into() } - fn cmd_help(&mut self, args: &Vec) -> CommandResult { + fn cmd_help(&mut self, args: &[String]) -> CommandResult { if let Some(command) = args.first() { match self.command_options.get(command) { Some(cmd) => { @@ -477,7 +477,7 @@ impl CommandHandler { } None => { println!("'{}' is an invalid command!", command); - self.cmd_help(&vec![]).ok(); + self.cmd_help(&[]).ok(); } } } else { @@ -489,11 +489,11 @@ impl CommandHandler { // Header println!( - "\n{}\n{}\n{}\n{}", + "\n{}\n{}\n+{}+\n{}", equal_bar, wrap_help_text("Help Menu", MAX_MENU_CHAR_WIDTH, 2), // Minus bar - format!("+{}+", BAR2_CHAR.repeat(MAX_MENU_CHAR_WIDTH)), + BAR2_CHAR.repeat(MAX_MENU_CHAR_WIDTH), empty_bar ); @@ -514,7 +514,7 @@ impl CommandHandler { Ok(()) } - fn cmd_adapter(&mut self, args: &Vec) -> CommandResult { + fn cmd_adapter(&mut self, args: &[String]) -> CommandResult { if !self.lock_context().manager_dbus.get_floss_enabled() { return Err("Floss is not enabled. First run, `floss enable`".into()); } @@ -665,7 +665,7 @@ impl CommandHandler { Ok(()) } - fn cmd_get_address(&mut self, _args: &Vec) -> CommandResult { + fn cmd_get_address(&mut self, _args: &[String]) -> CommandResult { if !self.lock_context().adapter_ready { return Err(self.adapter_not_ready()); } @@ -675,7 +675,7 @@ impl CommandHandler { Ok(()) } - fn cmd_discovery(&mut self, args: &Vec) -> CommandResult { + fn cmd_discovery(&mut self, args: &[String]) -> CommandResult { if !self.lock_context().adapter_ready { return Err(self.adapter_not_ready()); } @@ -695,7 +695,7 @@ impl CommandHandler { Ok(()) } - fn cmd_battery(&mut self, args: &Vec) -> CommandResult { + fn cmd_battery(&mut self, args: &[String]) -> CommandResult { if !self.lock_context().adapter_ready { return Err(self.adapter_not_ready()); } @@ -766,7 +766,7 @@ impl CommandHandler { Ok(()) } - fn cmd_bond(&mut self, args: &Vec) -> CommandResult { + fn cmd_bond(&mut self, args: &[String]) -> CommandResult { if !self.lock_context().adapter_ready { return Err(self.adapter_not_ready()); } @@ -825,7 +825,7 @@ impl CommandHandler { Ok(()) } - fn cmd_device(&mut self, args: &Vec) -> CommandResult { + fn cmd_device(&mut self, args: &[String]) -> CommandResult { if !self.lock_context().adapter_ready { return Err(self.adapter_not_ready()); } @@ -1059,7 +1059,7 @@ impl CommandHandler { Ok(()) } - fn cmd_floss(&mut self, args: &Vec) -> CommandResult { + fn cmd_floss(&mut self, args: &[String]) -> CommandResult { let command = get_arg(args, 0)?; match &command[..] { @@ -1083,7 +1083,7 @@ impl CommandHandler { Ok(()) } - fn cmd_gatt(&mut self, args: &Vec) -> CommandResult { + fn cmd_gatt(&mut self, args: &[String]) -> CommandResult { if !self.lock_context().adapter_ready { return Err(self.adapter_not_ready()); } @@ -1224,7 +1224,7 @@ impl CommandHandler { } "set-auth-req" => { let flag = match &get_arg(args, 1)?[..] { - "NONE" => AuthReq::NONE, + "NONE" => AuthReq::NoEnc, "EncNoMitm" => AuthReq::EncNoMitm, "EncMitm" => AuthReq::EncMitm, "SignedNoMitm" => AuthReq::SignedNoMitm, @@ -1535,7 +1535,7 @@ impl CommandHandler { Ok(()) } - fn cmd_le_scan(&mut self, args: &Vec) -> CommandResult { + fn cmd_le_scan(&mut self, args: &[String]) -> CommandResult { if !self.lock_context().adapter_ready { return Err(self.adapter_not_ready()); } @@ -1602,7 +1602,7 @@ impl CommandHandler { // TODO(b/233128828): More options will be implemented to test BLE advertising. // Such as setting advertising parameters, starting multiple advertising sets, etc. - fn cmd_advertise(&mut self, args: &Vec) -> CommandResult { + fn cmd_advertise(&mut self, args: &[String]) -> CommandResult { if !self.lock_context().adapter_ready { return Err(self.adapter_not_ready()); } @@ -1732,7 +1732,7 @@ impl CommandHandler { Ok(()) } - fn cmd_sdp(&mut self, args: &Vec) -> CommandResult { + fn cmd_sdp(&mut self, args: &[String]) -> CommandResult { if !self.lock_context().adapter_ready { return Err(self.adapter_not_ready()); } @@ -1757,7 +1757,7 @@ impl CommandHandler { Ok(()) } - fn cmd_socket(&mut self, args: &Vec) -> CommandResult { + fn cmd_socket(&mut self, args: &[String]) -> CommandResult { if !self.lock_context().adapter_ready { return Err(self.adapter_not_ready()); } @@ -1976,7 +1976,7 @@ impl CommandHandler { Ok(()) } - fn cmd_hid(&mut self, args: &Vec) -> CommandResult { + fn cmd_hid(&mut self, args: &[String]) -> CommandResult { if !self.context.lock().unwrap().adapter_ready { return Err(self.adapter_not_ready()); } @@ -2039,7 +2039,7 @@ impl CommandHandler { self.command_options.values().flat_map(|cmd| cmd.rules.clone()).collect() } - fn cmd_list_devices(&mut self, args: &Vec) -> CommandResult { + fn cmd_list_devices(&mut self, args: &[String]) -> CommandResult { if !self.lock_context().adapter_ready { return Err(self.adapter_not_ready()); } @@ -2077,7 +2077,7 @@ impl CommandHandler { Ok(()) } - fn cmd_telephony(&mut self, args: &Vec) -> CommandResult { + fn cmd_telephony(&mut self, args: &[String]) -> CommandResult { if !self.context.lock().unwrap().adapter_ready { return Err(self.adapter_not_ready()); } @@ -2301,7 +2301,7 @@ impl CommandHandler { Ok(()) } - fn cmd_qa(&mut self, args: &Vec) -> CommandResult { + fn cmd_qa(&mut self, args: &[String]) -> CommandResult { if !self.context.lock().unwrap().adapter_ready { return Err(self.adapter_not_ready()); } @@ -2328,7 +2328,7 @@ impl CommandHandler { Ok(()) } - fn cmd_media(&mut self, args: &Vec) -> CommandResult { + fn cmd_media(&mut self, args: &[String]) -> CommandResult { if !self.context.lock().unwrap().adapter_ready { return Err(self.adapter_not_ready()); } @@ -2345,7 +2345,7 @@ impl CommandHandler { Ok(()) } - fn cmd_dumpsys(&mut self, _args: &Vec) -> CommandResult { + fn cmd_dumpsys(&mut self, _args: &[String]) -> CommandResult { if !self.lock_context().adapter_ready { return Err(self.adapter_not_ready()); } diff --git a/system/gd/rust/linux/client/src/dbus_iface.rs b/system/gd/rust/linux/client/src/dbus_iface.rs index da5344f136c..eed0bed83db 100644 --- a/system/gd/rust/linux/client/src/dbus_iface.rs +++ b/system/gd/rust/linux/client/src/dbus_iface.rs @@ -520,14 +520,11 @@ impl DBusArg for ScanFilterCondition { condition: ScanFilterCondition, ) -> Result> { let mut map: dbus::arg::PropMap = std::collections::HashMap::new(); - match condition { - ScanFilterCondition::Patterns(patterns) => { - map.insert( - String::from("patterns"), - dbus::arg::Variant(Box::new(DBusArg::to_dbus(patterns)?)), - ); - } - _ => {} + if let ScanFilterCondition::Patterns(patterns) = condition { + map.insert( + String::from("patterns"), + dbus::arg::Variant(Box::new(DBusArg::to_dbus(patterns)?)), + ); } Ok(map) } @@ -715,6 +712,7 @@ impl_dbus_arg_enum!(BtDiscMode); // Implements RPC-friendly wrapper methods for calling IBluetooth, generated by // `generate_dbus_interface_client` below. +#[derive(Clone)] pub(crate) struct BluetoothDBusRPC { client_proxy: ClientDBusProxy, } @@ -1118,6 +1116,7 @@ pub struct AdapterWithEnabledDbus { // Implements RPC-friendly wrapper methods for calling IBluetoothManager, generated by // `generate_dbus_interface_client` below. +#[derive(Clone)] pub(crate) struct BluetoothManagerDBusRPC { client_proxy: ClientDBusProxy, } @@ -1333,6 +1332,7 @@ pub struct PeriodicAdvertisingParametersDBus { pub interval: i32, } +#[derive(Clone)] pub(crate) struct BluetoothAdminDBusRPC { client_proxy: ClientDBusProxy, } @@ -1428,6 +1428,7 @@ impl IBluetoothAdminPolicyCallback for IBluetoothAdminPolicyCallbackDBus { } } +#[derive(Clone)] pub(crate) struct BluetoothGattDBusRPC { client_proxy: ClientDBusProxy, } @@ -1521,6 +1522,7 @@ impl IBluetoothGatt for BluetoothGattDBus { } #[dbus_method("StartAdvertisingSet")] + #[allow(clippy::too_many_arguments)] fn start_advertising_set( &mut self, parameters: AdvertisingSetParameters, @@ -1757,6 +1759,7 @@ impl IBluetoothGatt for BluetoothGattDBus { } #[dbus_method("ConnectionParameterUpdate")] + #[allow(clippy::too_many_arguments)] fn connection_parameter_update( &self, client_id: i32, @@ -2102,6 +2105,7 @@ pub struct SocketResultDBus { id: u64, } +#[derive(Clone)] pub(crate) struct BluetoothSocketManagerDBusRPC { client_proxy: ClientDBusProxy, } @@ -2365,6 +2369,7 @@ impl ISuspendCallback for ISuspendCallbackDBus { fn on_resumed(&mut self, suspend_id: i32) {} } +#[derive(Clone)] pub(crate) struct BluetoothTelephonyDBusRPC { client_proxy: ClientDBusProxy, } @@ -2489,6 +2494,7 @@ impl IBluetoothTelephonyCallback for IBluetoothTelephonyCallbackDBus { } } +#[derive(Clone)] pub(crate) struct BluetoothQADBusRPC { client_proxy: ClientDBusProxy, } @@ -2608,6 +2614,7 @@ impl IBluetoothQACallback for IBluetoothQACallbackDBus { } } +#[derive(Clone)] pub(crate) struct BluetoothMediaDBusRPC { client_proxy: ClientDBusProxy, } @@ -2976,6 +2983,7 @@ impl IBluetoothMediaCallback for IBluetoothMediaCallbackDBus { fn on_lea_group_volume_changed(&mut self, group_id: i32, volume: u8) {} } +#[derive(Clone)] pub(crate) struct BatteryManagerDBusRPC { client_proxy: ClientDBusProxy, } diff --git a/system/gd/rust/linux/client/src/main.rs b/system/gd/rust/linux/client/src/main.rs index 91840597069..95aba9b62b6 100644 --- a/system/gd/rust/linux/client/src/main.rs +++ b/system/gd/rust/linux/client/src/main.rs @@ -804,7 +804,7 @@ async fn handle_client_command( break 'foreground_actions; } - handler.process_cmd_line(cmd, &rest.to_vec()); + handler.process_cmd_line(cmd, rest); break 'readline; } diff --git a/system/gd/rust/linux/dbus_projection/dbus_macros/src/lib.rs b/system/gd/rust/linux/dbus_projection/dbus_macros/src/lib.rs index dfb1a757227..430454d2165 100644 --- a/system/gd/rust/linux/dbus_projection/dbus_macros/src/lib.rs +++ b/system/gd/rust/linux/dbus_projection/dbus_macros/src/lib.rs @@ -644,6 +644,7 @@ pub fn dbus_propmap(attr: TokenStream, item: TokenStream) -> TokenStream { #field_ident.as_static_inner(0).unwrap(), format!("{}.{}", #struct_str, #field_str), )?; + #[allow(non_camel_case_types)] type #field_type_name = #field_type; let #field_ident = #field_type_name::from_dbus( #field_ident, @@ -1100,7 +1101,7 @@ pub fn generate_dbus_arg(_item: TokenStream) -> TokenStream { )))); } let arg = match (*any.downcast_ref::<::DBusType>().unwrap()).try_clone() { - Ok(foo) => foo, + Ok(arg) => arg, Err(_) => return Err(Box::new(DBusArgError::new(format!("{} cannot clone file.", name)))), }; -- GitLab From efe7e97cac18ee9643dbe7f4049648646a524b02 Mon Sep 17 00:00:00 2001 From: Hsin-chen Chuang Date: Mon, 17 Jun 2024 10:17:16 +0800 Subject: [PATCH 0061/1446] floss service: Fix clippy warnings - warning: this `MutexGuard` is held across an `await` point - warning: this function has too many arguments (17/7) - warning: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - warning: this import is redundant Bug: 343315863 Tag: #floss Test: mmm packages/modules/Bluetooth Test: ./build.py --target test Flag: EXEMPT, Floss-only changes Change-Id: I55366cf160c3d9f6335756c6d8f1cc1a6b1ae793 --- .../rust/linux/service/src/iface_bluetooth_gatt.rs | 13 +++++-------- .../gd/rust/linux/service/src/interface_manager.rs | 2 +- system/gd/rust/linux/service/src/main.rs | 7 ++++--- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs b/system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs index d7f95ce8ef8..04afea5c210 100644 --- a/system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs +++ b/system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs @@ -446,14 +446,11 @@ impl DBusArg for ScanFilterCondition { condition: ScanFilterCondition, ) -> Result> { let mut map: dbus::arg::PropMap = std::collections::HashMap::new(); - match condition { - ScanFilterCondition::Patterns(patterns) => { - map.insert( - String::from("patterns"), - dbus::arg::Variant(Box::new(DBusArg::to_dbus(patterns)?)), - ); - } - _ => {} + if let ScanFilterCondition::Patterns(patterns) = condition { + map.insert( + String::from("patterns"), + dbus::arg::Variant(Box::new(DBusArg::to_dbus(patterns)?)), + ); } Ok(map) } diff --git a/system/gd/rust/linux/service/src/interface_manager.rs b/system/gd/rust/linux/service/src/interface_manager.rs index 2c027824312..2f6dc89ca09 100644 --- a/system/gd/rust/linux/service/src/interface_manager.rs +++ b/system/gd/rust/linux/service/src/interface_manager.rs @@ -48,7 +48,7 @@ impl InterfaceManager { /// * `disconnect_watcher` - DisconnectWatcher to monitor client disconnects /// * `bluetooth` - Implementation of the Bluetooth API /// other implementations follow. - /// + #[allow(clippy::too_many_arguments)] pub async fn dispatch( mut rx: Receiver, tx: Sender, diff --git a/system/gd/rust/linux/service/src/main.rs b/system/gd/rust/linux/service/src/main.rs index 31f89f7ee6f..9c01c5c66a3 100644 --- a/system/gd/rust/linux/service/src/main.rs +++ b/system/gd/rust/linux/service/src/main.rs @@ -10,7 +10,7 @@ use std::time::Duration; use tokio::sync::mpsc::Sender; // Necessary to link right entries. -#[allow(unused_imports)] +#[allow(clippy::single_component_path_imports, unused_imports)] use bt_shim; use bt_topshim::{btif::get_btinterface, topstack}; @@ -215,8 +215,9 @@ fn main() -> Result<(), Box> { )); // Set up the disconnect watcher to monitor client disconnects. - let disconnect_watcher = Arc::new(Mutex::new(DisconnectWatcher::new())); - disconnect_watcher.lock().unwrap().setup_watch(conn.clone()).await; + let mut disconnect_watcher = DisconnectWatcher::new(); + disconnect_watcher.setup_watch(conn.clone()).await; + let disconnect_watcher = Arc::new(Mutex::new(disconnect_watcher)); tokio::spawn(interface_manager::InterfaceManager::dispatch( api_rx, -- GitLab From 60b70d24fd15ed7434afe1e5c1781dcaa04a53fc Mon Sep 17 00:00:00 2001 From: Hsin-chen Chuang Date: Mon, 17 Jun 2024 11:21:05 +0800 Subject: [PATCH 0062/1446] floss mgmt: Fix clippy warnings - warning: this `MutexGuard` is held across an `await` point - warning: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let` - warning: methods with the following characteristics: (`to_*` and `self` type is `Copy`) usually take `self` by value - warning: match expression looks like `matches!` macro - warning: use of `format!` to build up a string from an iterator - warning: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` - warning: you seem to want to iterate on a map's values Bug: 343315863 Tag: #floss Test: mmm packages/modules/Bluetooth Test: ./build.py --target test Flag: EXEMPT, Floss-only changes Change-Id: Ief38ba9b870d952e52f8d8099c480c25bb03a67c --- .../rust/linux/mgmt/src/bluetooth_manager.rs | 17 +++---- system/gd/rust/linux/mgmt/src/config_util.rs | 16 +++--- system/gd/rust/linux/mgmt/src/main.rs | 5 +- system/gd/rust/linux/mgmt/src/migrate.rs | 49 +++++++++---------- .../gd/rust/linux/mgmt/src/state_machine.rs | 18 +++---- 5 files changed, 45 insertions(+), 60 deletions(-) diff --git a/system/gd/rust/linux/mgmt/src/bluetooth_manager.rs b/system/gd/rust/linux/mgmt/src/bluetooth_manager.rs index 41ffb358e91..ca98b2ba9be 100644 --- a/system/gd/rust/linux/mgmt/src/bluetooth_manager.rs +++ b/system/gd/rust/linux/mgmt/src/bluetooth_manager.rs @@ -51,7 +51,7 @@ impl BluetoothManager { } else { warn!("Presence removed: {}", hci); } - for (_, callback) in &mut self.callbacks { + for callback in self.callbacks.values_mut() { callback.on_hci_device_changed(hci.to_i32(), present); } } @@ -63,13 +63,13 @@ impl BluetoothManager { warn!("Stopped {}", hci); } - for (_, callback) in &mut self.callbacks { + for callback in self.callbacks.values_mut() { callback.on_hci_enabled_changed(hci.to_i32(), enabled); } } pub(crate) fn callback_default_adapter_change(&mut self, hci: VirtualHciIndex) { - for (_, callback) in &mut self.callbacks { + for callback in self.callbacks.values_mut() { callback.on_default_adapter_changed(hci.to_i32()); } } @@ -272,14 +272,9 @@ fn floss_have_le_devices() -> bool { impl IBluetoothExperimental for BluetoothManager { fn set_ll_privacy(&mut self, enabled: bool) -> bool { warn!("Set Floss LL Privacy={}", enabled); - let current_status = match config_util::read_floss_ll_privacy_enabled() { - Ok(true) => true, - _ => false, - }; - let current_address_status = match config_util::read_floss_address_privacy_enabled() { - Ok(true) => true, - _ => false, - }; + let current_status = matches!(config_util::read_floss_ll_privacy_enabled(), Ok(true)); + let current_address_status = + matches!(config_util::read_floss_address_privacy_enabled(), Ok(true)); let mut need_restart = current_status != enabled; diff --git a/system/gd/rust/linux/mgmt/src/config_util.rs b/system/gd/rust/linux/mgmt/src/config_util.rs index acce9ed08e9..c7f452bfe36 100644 --- a/system/gd/rust/linux/mgmt/src/config_util.rs +++ b/system/gd/rust/linux/mgmt/src/config_util.rs @@ -143,14 +143,14 @@ pub fn get_default_adapter() -> VirtualHciIndex { } pub fn set_default_adapter(hci: VirtualHciIndex) -> bool { - match read_config().ok().and_then(|config| { - let mut cfg = serde_json::from_str::(config.as_str()).ok()?; - cfg[DEFAULT_ADAPTER_KEY] = serde_json::to_value(hci.to_i32()).ok().unwrap(); - serde_json::ser::to_string_pretty(&cfg).ok() - }) { - Some(s) => std::fs::write(BTMANAGERD_CONF, s).is_ok(), - None => false, - } + (|| { + let config: String = read_config()?; + let mut cfg = serde_json::from_str::(config.as_str())?; + cfg[DEFAULT_ADAPTER_KEY] = serde_json::to_value(hci.to_i32())?; + let new_config: String = serde_json::ser::to_string_pretty(&cfg)?; + std::fs::write(BTMANAGERD_CONF, new_config) + })() + .is_ok() } fn list_hci_devices_string() -> Vec { diff --git a/system/gd/rust/linux/mgmt/src/main.rs b/system/gd/rust/linux/mgmt/src/main.rs index 31291122254..f88075ed98f 100644 --- a/system/gd/rust/linux/mgmt/src/main.rs +++ b/system/gd/rust/linux/mgmt/src/main.rs @@ -110,8 +110,9 @@ pub async fn main() -> Result<(), Box> { let bluetooth_manager = Arc::new(Mutex::new(Box::new(BluetoothManager::new(proxy)))); // Set up the disconnect watcher to monitor client disconnects. - let disconnect_watcher = Arc::new(Mutex::new(DisconnectWatcher::new())); - disconnect_watcher.lock().unwrap().setup_watch(conn.clone()).await; + let mut disconnect_watcher = DisconnectWatcher::new(); + disconnect_watcher.setup_watch(conn.clone()).await; + let disconnect_watcher = Arc::new(Mutex::new(disconnect_watcher)); // We add the Crossroads instance to the connection so that incoming method calls will be // handled. diff --git a/system/gd/rust/linux/mgmt/src/migrate.rs b/system/gd/rust/linux/mgmt/src/migrate.rs index e1a0a9aa51d..5352a10df67 100644 --- a/system/gd/rust/linux/mgmt/src/migrate.rs +++ b/system/gd/rust/linux/mgmt/src/migrate.rs @@ -11,6 +11,7 @@ //! all others use std::collections::HashMap; +use std::fmt::Write; use std::fs; use std::path::Path; @@ -242,7 +243,10 @@ fn dec_str_to_hex_str(str: String) -> Result { fn base64_str_to_hex_str(str: String) -> Result { match base64::decode(str) { Ok(bytes) => { - let res: String = bytes.iter().map(|b| format!("{:02x}", b)).collect(); + let res: String = bytes.iter().fold(String::new(), |mut res, b| { + let _ = write!(res, "{:02x}", b); + res + }); Ok(res) } Err(err) => Err(format!("Error converting from base64 string to hex string: {}", err)), @@ -616,19 +620,16 @@ pub fn migrate_bluez_devices() { fn merge_and_write_bluez_conf(filepath: String, conf: &mut Ini) { let mut existing_conf = Ini::new_cs(); existing_conf.set_comment_symbols(&['!', '#']); - match existing_conf.load(filepath.clone()) { + if let Ok(ini) = existing_conf.load(filepath.clone()) { // Device already exists in BlueZ - Ok(ini) => { - for (sec, props) in ini { - // Keep keys that weren't transferrable - for (k, v) in props { - if conf.get(sec.as_str(), k.as_str()).is_none() { - conf.set(sec.as_str(), k.as_str(), v); - } + for (sec, props) in ini { + // Keep keys that weren't transferrable + for (k, v) in props { + if conf.get(sec.as_str(), k.as_str()).is_none() { + conf.set(sec.as_str(), k.as_str(), v); } } } - Err(_) => {} } // Write BlueZ file match conf.write(filepath.clone()) { @@ -880,26 +881,20 @@ fn convert_floss_conf(filename: &str) { } // Delete devices that exist in BlueZ but not in Floss - match glob(format!("{}/{}/*:*", BT_LIBDIR, adapter_addr).as_str()) { - Ok(globbed) => { - for entry in globbed { - let pathbuf = entry.unwrap_or_default(); - let addrs = pathbuf.to_str().unwrap_or_default().split('/').collect::>(); - let device_addr: String = addrs[addrs.len() - 1].into(); - if !devices.contains(&device_addr.to_lowercase()) { - match fs::remove_dir_all(pathbuf) { - Ok(_) => (), - Err(err) => { - warn!( - "Error removing {} during Floss to BlueZ device migration: {}", - device_addr, err - ); - } - } + if let Ok(globbed) = glob(format!("{}/{}/*:*", BT_LIBDIR, adapter_addr).as_str()) { + for entry in globbed { + let pathbuf = entry.unwrap_or_default(); + let addrs = pathbuf.to_str().unwrap_or_default().split('/').collect::>(); + let device_addr: String = addrs[addrs.len() - 1].into(); + if !devices.contains(&device_addr.to_lowercase()) { + if let Err(err) = fs::remove_dir_all(pathbuf) { + warn!( + "Error removing {} during Floss to BlueZ device migration: {}", + device_addr, err + ); } } } - _ => (), } } diff --git a/system/gd/rust/linux/mgmt/src/state_machine.rs b/system/gd/rust/linux/mgmt/src/state_machine.rs index aa363774a7d..c24e34efdb1 100644 --- a/system/gd/rust/linux/mgmt/src/state_machine.rs +++ b/system/gd/rust/linux/mgmt/src/state_machine.rs @@ -54,10 +54,7 @@ pub enum ProcessState { /// Check whether adapter is enabled by checking internal state. pub fn state_to_enabled(state: ProcessState) -> bool { - match state { - ProcessState::On | ProcessState::TurningOff => true, - _ => false, - } + matches!(state, ProcessState::On | ProcessState::TurningOff) } /// Device path of hci device in sysfs. This will uniquely identify a Bluetooth @@ -73,7 +70,7 @@ pub const INVALID_HCI_INDEX: i32 = -1; #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct VirtualHciIndex(pub i32); impl VirtualHciIndex { - pub(crate) fn to_i32(&self) -> i32 { + pub(crate) fn to_i32(self) -> i32 { self.0 } } @@ -87,7 +84,7 @@ impl Display for VirtualHciIndex { #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] pub struct RealHciIndex(pub i32); impl RealHciIndex { - pub(crate) fn to_i32(&self) -> i32 { + pub(crate) fn to_i32(self) -> i32 { self.0 } } @@ -850,18 +847,15 @@ pub async fn mainloop( } } }); - match context + if let Some(handle) = context .state_machine .process_monitor .lock() .unwrap() .insert(fname.clone(), handle) { - Some(handle) => { - warn!("{}: Aborting old handler", hci); - handle.abort(); - } - None => {} + warn!("{}: Aborting old handler", hci); + handle.abort(); } } _ => debug!("Invalid pid path: {}", fname), -- GitLab From 8589566fbf8f9c5050bb986ab5d6646d75d1d142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Kongstad?= Date: Mon, 17 Jun 2024 17:18:54 +0200 Subject: [PATCH 0063/1446] Baseline Lint FlaggedApi violations The Lint FlaggedApi checks are currently configured as warnings. Add existing violations to baselines files to prepare for turning the FlaggedApi checks into errors. Bug: 303434307 Test: treehugger Flag: EXEMPT not possible to flag baseline changes Ignore-AOSP-First: add baselines to internal branches before AOSP to prevent merge conflicts Change-Id: I990ce57cd5cdac44ee8b93565b45aa15790ad697 --- framework/Android.bp | 1 + framework/lint-baseline.xml | 488 ++++++++++++++++++++++++++++++++++++ 2 files changed, 489 insertions(+) create mode 100644 framework/lint-baseline.xml diff --git a/framework/Android.bp b/framework/Android.bp index 8f009c49410..f209ddeed4a 100644 --- a/framework/Android.bp +++ b/framework/Android.bp @@ -114,6 +114,7 @@ java_sdk_library { }, lint: { strict_updatability_linting: true, + baseline_filename: "lint-baseline.xml", }, } diff --git a/framework/lint-baseline.xml b/framework/lint-baseline.xml new file mode 100644 index 00000000000..3924839a90c --- /dev/null +++ b/framework/lint-baseline.xml @@ -0,0 +1,488 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- GitLab From 8455a3b886e20ee536f99f4376a75b1eeb2179b9 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Tue, 11 Jun 2024 13:04:45 -0700 Subject: [PATCH 0064/1446] stack::rfcomm Extract get_port_from_mcb Bug: 347001813 Test: atest net_test_stack_rfcomm Flag: EXEMPT, Mechanical Refactor Change-Id: I42647671c4a9b99014b2e82e43f3919eff920fb5 --- system/stack/Android.bp | 1 + system/stack/rfcomm/port_api.cc | 21 ++++--- .../test/rfcomm/stack_rfcomm_port_test.cc | 57 +++++++++++++++++++ 3 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 system/stack/test/rfcomm/stack_rfcomm_port_test.cc diff --git a/system/stack/Android.bp b/system/stack/Android.bp index 567d4211462..dc04b2c7452 100644 --- a/system/stack/Android.bp +++ b/system/stack/Android.bp @@ -830,6 +830,7 @@ cc_test { "test/common/mock_btm_layer.cc", "test/common/mock_l2cap_layer.cc", "test/common/stack_test_packet_utils.cc", + "test/rfcomm/stack_rfcomm_port_test.cc", "test/rfcomm/stack_rfcomm_test.cc", "test/rfcomm/stack_rfcomm_test_main.cc", "test/rfcomm/stack_rfcomm_test_utils.cc", diff --git a/system/stack/rfcomm/port_api.cc b/system/stack/rfcomm/port_api.cc index d288641f05b..aa36f155535 100644 --- a/system/stack/rfcomm/port_api.cc +++ b/system/stack/rfcomm/port_api.cc @@ -493,6 +493,17 @@ int PORT_CheckConnection(uint16_t handle, RawAddress* bd_addr, * bd_addr - bd_addr of the peer * ******************************************************************************/ +static const tPORT* get_port_from_mcb(const tRFC_MCB* multiplexer_cb) { + tPORT* p_port = nullptr; + + for (tPORT& port : rfc_cb.port.port) { + if (port.rfc.p_mcb == multiplexer_cb) { + return &port; + } + } + return nullptr; +} + bool PORT_IsOpening(RawAddress* bd_addr) { /* Check for any rfc_mcb which is in the middle of opening. */ for (auto& multiplexer_cb : rfc_cb.port.rfc_mcb) { @@ -505,15 +516,7 @@ bool PORT_IsOpening(RawAddress* bd_addr) { } if (multiplexer_cb.state == RFC_MX_STATE_CONNECTED) { - tPORT* p_port = nullptr; - - for (tPORT& port : rfc_cb.port.port) { - if (port.rfc.p_mcb == &multiplexer_cb) { - p_port = &port; - break; - } - } - + const tPORT* p_port = get_port_from_mcb(&multiplexer_cb); log::info("RFC_MX_STATE_CONNECTED, found_port={}, tRFC_PORT_STATE={}", (p_port != nullptr) ? "T" : "F", (p_port != nullptr) ? p_port->rfc.state : 0); diff --git a/system/stack/test/rfcomm/stack_rfcomm_port_test.cc b/system/stack/test/rfcomm/stack_rfcomm_port_test.cc new file mode 100644 index 00000000000..e2c1b96f49b --- /dev/null +++ b/system/stack/test/rfcomm/stack_rfcomm_port_test.cc @@ -0,0 +1,57 @@ +/* + * 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 + +#include "stack/include/port_api.h" +#include "stack/rfcomm/rfc_int.h" +#include "types/raw_address.h" + +namespace { +const RawAddress kRawAddress = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); + +} // namespace + +class StackRfcommPortTest : public ::testing::Test { + protected: + void SetUp() override {} + void TearDown() override {} + + private: +}; + +TEST_F(StackRfcommPortTest, PORT_IsOpening__basic) { + RawAddress bd_addr(kRawAddress); + + rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_IDLE; + ASSERT_FALSE(PORT_IsOpening(&bd_addr)); + rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_WAIT_CONN_CNF; + ASSERT_TRUE(PORT_IsOpening(&bd_addr)); + rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_CONFIGURE; + ASSERT_TRUE(PORT_IsOpening(&bd_addr)); + rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_SABME_WAIT_UA; + ASSERT_TRUE(PORT_IsOpening(&bd_addr)); + rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_WAIT_SABME; + ASSERT_TRUE(PORT_IsOpening(&bd_addr)); + rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_CONNECTED; + rfc_cb.port.port[0].rfc.p_mcb = &rfc_cb.port.rfc_mcb[0]; + rfc_cb.port.port[0].rfc.state = RFC_STATE_OPENED; + ASSERT_FALSE(PORT_IsOpening(&bd_addr)); + rfc_cb.port.port[0].rfc.state = RFC_STATE_TERM_WAIT_SEC_CHECK; + ASSERT_TRUE(PORT_IsOpening(&bd_addr)); + rfc_cb.port.rfc_mcb[0].state = RFC_MX_STATE_DISC_WAIT_UA; + ASSERT_FALSE(PORT_IsOpening(&bd_addr)); +} -- GitLab From c1b377bb1abb528c1b7c8f01edba29de00421f31 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Tue, 18 Jun 2024 17:31:22 +0000 Subject: [PATCH 0065/1446] Revert "Add flag a2dp_check_lea_iso_channel" Revert submission 3124914 Reason for revert: Droidfood blocking bug: b/347848255 Reverted changes: /q/submissionid:3124914 (cherry picked from https://android-review.googlesource.com/q/commit:2c305ec15c1ed2c60c74f0009259daa371d5b8d7) (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:2a33d3e14049531b8689c2fc549e70afdaa35f22) Merged-In: I84ae69970c1061636e3b25fbcfe1472bb67185b0 Change-Id: I84ae69970c1061636e3b25fbcfe1472bb67185b0 --- flags/a2dp.aconfig | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/flags/a2dp.aconfig b/flags/a2dp.aconfig index ddb191b7d7b..4df649b8030 100644 --- a/flags/a2dp.aconfig +++ b/flags/a2dp.aconfig @@ -75,13 +75,3 @@ flag { purpose: PURPOSE_BUGFIX } } - -flag { - name: "a2dp_check_lea_iso_channel" - namespace: "bluetooth" - description: "Prevent A2DP stream from starting when LEA ISO channels are in use" - bug: "346475618" - metadata { - purpose: PURPOSE_BUGFIX - } -} -- GitLab From 74feaa08244963ca6c195b0bc3a77311394007d9 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Tue, 18 Jun 2024 17:31:12 +0000 Subject: [PATCH 0066/1446] Revert "Add checking for active ISO channels before starting A2D..." Revert submission 3124914 Reason for revert: Droidfood blocking bug: b/347848255 Reverted changes: /q/submissionid:3124914 (cherry picked from https://android-review.googlesource.com/q/commit:4b46c62960371104eaa4437cdc849043619fa3f1) (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:1aa6fa1a49225ab0e363b5d4f7fb545073d5f031) Merged-In: Id2f7394e86b49651e517d011d43b7a1026250554 Change-Id: Id2f7394e86b49651e517d011d43b7a1026250554 --- system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc | 10 ---------- system/stack/btm/btm_iso.cc | 4 ---- system/stack/btm/btm_iso_impl.h | 6 ------ system/stack/include/btm_iso_api.h | 5 ----- system/test/mock/mock_stack_btm_iso.cc | 4 ---- system/test/mock/mock_stack_btm_iso.h | 1 - 6 files changed, 30 deletions(-) diff --git a/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc b/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc index d49c3672d70..a8fc262dad9 100644 --- a/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc +++ b/system/audio_hal_interface/aidl/a2dp_encoding_aidl.cc @@ -18,7 +18,6 @@ #include "a2dp_encoding_aidl.h" #include -#include #include @@ -27,7 +26,6 @@ #include "audio_aidl_interfaces.h" #include "bta/av/bta_av_int.h" #include "btif/include/btif_common.h" -#include "btm_iso_api.h" #include "codec_status_aidl.h" #include "transport_instance.h" @@ -99,14 +97,6 @@ BluetoothAudioCtrlAck A2dpTransport::StartRequest(bool is_low_latency) { return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_INCALL_FAILURE); } - if (com::android::bluetooth::flags::a2dp_check_lea_iso_channel()) { - // Don't send START request to stack while LEA sessions are in use - if (hci::IsoManager::GetInstance()->GetNumberOfActiveIso() > 0) { - log::error("LEA currently has active ISO channels"); - return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE); - } - } - if (btif_av_stream_started_ready(A2dpType::kSource)) { // Already started, ACK back immediately. return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS); diff --git a/system/stack/btm/btm_iso.cc b/system/stack/btm/btm_iso.cc index e8eeec3a59b..4f9a94449c2 100644 --- a/system/stack/btm/btm_iso.cc +++ b/system/stack/btm/btm_iso.cc @@ -90,10 +90,6 @@ void IsoManager::DisconnectCis(uint16_t cis_handle, uint8_t reason) { pimpl_->iso_impl_->disconnect_cis(cis_handle, reason); } -int IsoManager::GetNumberOfActiveIso() { - return pimpl_->iso_impl_->get_number_of_active_iso(); -} - void IsoManager::SetupIsoDataPath( uint16_t iso_handle, struct iso_manager::iso_data_path_params path_params) { pimpl_->iso_impl_->setup_iso_data_path(iso_handle, std::move(path_params)); diff --git a/system/stack/btm/btm_iso_impl.h b/system/stack/btm/btm_iso_impl.h index 0b124e9e3ad..276f1985a7c 100644 --- a/system/stack/btm/btm_iso_impl.h +++ b/system/stack/btm/btm_iso_impl.h @@ -342,12 +342,6 @@ struct iso_impl { hci_reason_code_text((tHCI_REASON)(reason)).c_str())); } - int get_number_of_active_iso() { - int num_iso = conn_hdl_to_cis_map_.size() + conn_hdl_to_bis_map_.size(); - log::info("Current number of active_iso is {}", num_iso); - return num_iso; - } - void on_setup_iso_data_path(uint8_t* stream, uint16_t /* len */) { uint8_t status; uint16_t conn_handle; diff --git a/system/stack/include/btm_iso_api.h b/system/stack/include/btm_iso_api.h index 7e968e9d31d..eb1bf376181 100644 --- a/system/stack/include/btm_iso_api.h +++ b/system/stack/include/btm_iso_api.h @@ -226,11 +226,6 @@ class IsoManager { virtual void HandleHciEvent(uint8_t sub_code, uint8_t* params, uint16_t length); - /** - * Return the current number of ISO channels - */ - virtual int GetNumberOfActiveIso(); - /** * Starts the IsoManager module */ diff --git a/system/test/mock/mock_stack_btm_iso.cc b/system/test/mock/mock_stack_btm_iso.cc index 06d1a4096ef..436a31c8e5e 100644 --- a/system/test/mock/mock_stack_btm_iso.cc +++ b/system/test/mock/mock_stack_btm_iso.cc @@ -157,10 +157,6 @@ void IsoManager::Stop() { mock_pimpl_ = nullptr; } -int IsoManager::GetNumberOfActiveIso() { - return pimpl_->GetNumberOfActiveIso(); -} - void IsoManager::Dump(int /* fd */) {} IsoManager::~IsoManager() = default; diff --git a/system/test/mock/mock_stack_btm_iso.h b/system/test/mock/mock_stack_btm_iso.h index 4d7a49634e5..9948f4cdf85 100644 --- a/system/test/mock/mock_stack_btm_iso.h +++ b/system/test/mock/mock_stack_btm_iso.h @@ -50,7 +50,6 @@ struct MockIsoManager { (void), EstablishCis, (struct bluetooth::hci::iso_manager::cis_establish_params conn_params)); MOCK_METHOD((void), DisconnectCis, (uint16_t cis_handle, uint8_t reason)); - MOCK_METHOD((int), GetNumberOfActiveIso, ()); MOCK_METHOD( (void), SetupIsoDataPath, (uint16_t iso_handle, -- GitLab From c03efad34ed0f523751d95e473e0e9563ffa6316 Mon Sep 17 00:00:00 2001 From: Yuyang Huang Date: Tue, 18 Jun 2024 18:46:18 +0000 Subject: [PATCH 0067/1446] Remove auto_connect_on_hfp_when_no_a2dp_device flag This flag was added in Android U to enable auto-connecting to HFP devices when there is no A2DP device to connect to. This flag has been enabled by default since 24Q2, and there have been no reports of any issues with it. Therefore, it is safe to remove this flag. Change-Id: Ic73e00116cc1d766d997eb76ba89850bbc2f6569 Test: atest PhonePolicyTest Bug: 347316578 Flag: exempt, remove nextfood flag --- .../src/com/android/bluetooth/btservice/PhonePolicy.java | 5 ----- .../com/android/bluetooth/btservice/PhonePolicyTest.java | 3 --- flags/hfp.aconfig | 7 ------- 3 files changed, 15 deletions(-) diff --git a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java index c09e01b59e0..67d55b83ace 100644 --- a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java +++ b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java @@ -887,11 +887,6 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback { return; } - if (!Flags.autoConnectOnHfpWhenNoA2dpDevice()) { - debugLog("HFP auto connect is not enabled"); - return; - } - if (Flags.autoConnectOnMultipleHfpWhenNoA2dpDevice()) { final List mostRecentlyConnectedHfpDevices = mDatabaseManager.getMostRecentlyActiveHfpDevices(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java index dcfe71349aa..43975ca1d1f 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/PhonePolicyTest.java @@ -1071,7 +1071,6 @@ public class PhonePolicyTest { */ @Test public void testAutoConnectHfpOnly() { - mSetFlagsRule.enableFlags(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE); mSetFlagsRule.disableFlags(Flags.FLAG_AUTO_CONNECT_ON_MULTIPLE_HFP_WHEN_NO_A2DP_DEVICE); // Return desired values from the mocked object(s) @@ -1109,7 +1108,6 @@ public class PhonePolicyTest { @Test public void autoConnect_whenMultiHfp_startConnection() { - mSetFlagsRule.enableFlags(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE); mSetFlagsRule.enableFlags(Flags.FLAG_AUTO_CONNECT_ON_MULTIPLE_HFP_WHEN_NO_A2DP_DEVICE); // Return desired values from the mocked object(s) @@ -1154,7 +1152,6 @@ public class PhonePolicyTest { @Test public void autoConnect_whenMultiHfpAndDeconnection_startConnection() { mSetFlagsRule.enableFlags(Flags.FLAG_AUTO_CONNECT_ON_MULTIPLE_HFP_WHEN_NO_A2DP_DEVICE); - mSetFlagsRule.enableFlags(Flags.FLAG_AUTO_CONNECT_ON_HFP_WHEN_NO_A2DP_DEVICE); // Return desired values from the mocked object(s) doReturn(BluetoothAdapter.STATE_ON).when(mAdapterService).getState(); diff --git a/flags/hfp.aconfig b/flags/hfp.aconfig index 45e20865794..17c23490ca8 100644 --- a/flags/hfp.aconfig +++ b/flags/hfp.aconfig @@ -1,13 +1,6 @@ package: "com.android.bluetooth.flags" container: "com.android.btservices" -flag { - name: "auto_connect_on_hfp_when_no_a2dp_device" - namespace: "bluetooth" - description: "Auto connect to hfp device is there is no a2dp device to connect to" - bug: "305799237" -} - flag { name: "auto_connect_on_multiple_hfp_when_no_a2dp_device" namespace: "bluetooth" -- GitLab From f4a3bdab4fe8a3e41747eb8f4573859aaf96a2fc Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Fri, 24 May 2024 18:06:17 -0700 Subject: [PATCH 0068/1446] [4/19] get_btm_client_interface().lifecycle.BTM_reset_complete Bug: 343772702 Test: m . Flag: EXEMPT, Mechanical Refactor Change-Id: I9d5c70b8be799f7cd0d94f1d53c85621b3a2571f --- system/btif/src/stack_manager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/btif/src/stack_manager.cc b/system/btif/src/stack_manager.cc index 7ed50f45abb..3192175f7dc 100644 --- a/system/btif/src/stack_manager.cc +++ b/system/btif/src/stack_manager.cc @@ -313,7 +313,7 @@ static void event_start_up_stack(bluetooth::core::CoreInterface* interface, bta_dm_enable(btif_dm_sec_evt, btif_dm_acl_evt); btm_acl_device_down(); - BTM_reset_complete(); + get_btm_client_interface().lifecycle.BTM_reset_complete(); BTA_dm_on_hw_on(); -- GitLab From dc2a52f21c404a41c5cce9adcf6f3d0b4c621151 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Tue, 18 Jun 2024 01:01:33 +0000 Subject: [PATCH 0069/1446] Revert^2 "stack::inq Finalize extract inquiry API" This reverts commit d85ddd2e596b5afcfec3fd4d061b671b4f424e1e. Reason for revert: Builds ok with fix Change-Id: Idcdd7b31f43a9e666cdde0a7390d2e3006b928c8 --- system/bta/dm/bta_dm_act.cc | 1 + system/stack/btm/btm_inq.cc | 3 +- system/stack/include/btm_api.h | 117 -------------------- system/stack/include/btm_inq.h | 36 +++++- system/stack/test/btm/stack_btm_inq_test.cc | 3 +- 5 files changed, 33 insertions(+), 127 deletions(-) diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc index 585b4198455..a199c45a293 100644 --- a/system/bta/dm/bta_dm_act.cc +++ b/system/bta/dm/bta_dm_act.cc @@ -58,6 +58,7 @@ #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" #include "stack/include/btm_client_interface.h" +#include "stack/include/btm_inq.h" #include "stack/include/gatt_api.h" #include "stack/include/l2c_api.h" #include "stack/include/main_thread.h" diff --git a/system/stack/btm/btm_inq.cc b/system/stack/btm/btm_inq.cc index 0304b87218c..983748ce15b 100644 --- a/system/stack/btm/btm_inq.cc +++ b/system/stack/btm/btm_inq.cc @@ -42,7 +42,7 @@ #include "common/time_util.h" #include "hci/controller_interface.h" #include "hci/event_checkers.h" -#include "hci/hci_layer.h" +#include "hci/hci_interface.h" #include "internal_include/bt_target.h" #include "main/shim/acl_api.h" #include "main/shim/entry.h" @@ -62,7 +62,6 @@ #include "stack/include/bt_lap.h" #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" -#include "stack/include/btm_api.h" #include "stack/include/btm_ble_api.h" #include "stack/include/btm_log_history.h" #include "stack/include/hci_error_code.h" diff --git a/system/stack/include/btm_api.h b/system/stack/include/btm_api.h index 5d5082903c2..d629a625cc1 100644 --- a/system/stack/include/btm_api.h +++ b/system/stack/include/btm_api.h @@ -168,123 +168,6 @@ void BTM_WriteVoiceSettings(uint16_t settings); ******************************************************************************/ [[nodiscard]] tBTM_STATUS BTM_EnableTestMode(void); -/******************************************************************************* - * DEVICE DISCOVERY FUNCTIONS - Inquiry, Remote Name, Discovery, Class of Device - ******************************************************************************/ - -/******************************************************************************* - * - * Function BTM_SetDiscoverability - * - * Description This function is called to set the device into or out of - * discoverable mode. Discoverable mode means inquiry - * scans are enabled. If a value of '0' is entered for window - * or interval, the default values are used. - * - * Returns BTM_SUCCESS if successful - * BTM_BUSY if a setting of the filter is already in progress - * BTM_NO_RESOURCES if couldn't get a memory pool buffer - * BTM_ILLEGAL_VALUE if a bad parameter was detected - * BTM_WRONG_MODE if the device is not up. - * - ******************************************************************************/ -[[nodiscard]] tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode); - -/******************************************************************************* - * - * Function BTM_StartInquiry - * - * Description This function is called to start an inquiry. - * - * Parameters: p_inqparms - pointer to the inquiry information - * mode - GENERAL or LIMITED inquiry - * duration - length in 1.28 sec intervals (If '0', the - * inquiry is CANCELLED) - * filter_cond_type - BTM_CLR_INQUIRY_FILTER, - * BTM_FILTER_COND_DEVICE_CLASS, or - * BTM_FILTER_COND_BD_ADDR - * filter_cond - value for the filter (based on - * filter_cond_type) - * - * p_results_cb - Pointer to the callback routine which gets - * called upon receipt of an inquiry result. If - * this field is NULL, the application is not - * notified. - * - * p_cmpl_cb - Pointer to the callback routine which gets - * called upon completion. If this field is - * NULL, the application is not notified when - * completed. - * Returns tBTM_STATUS - * BTM_CMD_STARTED if successfully initiated - * BTM_BUSY if already in progress - * BTM_ILLEGAL_VALUE if parameter(s) are out of range - * BTM_NO_RESOURCES if could not allocate resources to start - * the command - * BTM_WRONG_MODE if the device is not up. - * - ******************************************************************************/ -[[nodiscard]] tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, - tBTM_CMPL_CB* p_cmpl_cb); - -/******************************************************************************* - * - * Function BTM_IsInquiryActive - * - * Description Return a bit mask of the current inquiry state - * - * Returns Bitmask of current inquiry state - * - ******************************************************************************/ -[[nodiscard]] uint16_t BTM_IsInquiryActive(void); - -/******************************************************************************* - * - * Function BTM_CancelInquiry - * - * Description This function cancels an inquiry if active - * - ******************************************************************************/ -void BTM_CancelInquiry(void); - -/******************************************************************************* - * - * Function BTM_SetConnectability - * - * Description This function is called to set the device into or out of - * connectable mode. Discoverable mode means page scans are - * enabled. - * - * Returns BTM_SUCCESS if successful - * BTM_ILLEGAL_VALUE if a bad parameter is detected - * BTM_NO_RESOURCES if could not allocate a message buffer - * BTM_WRONG_MODE if the device is not up. - * - ******************************************************************************/ -[[nodiscard]] tBTM_STATUS BTM_SetConnectability(uint16_t page_mode); - -/******************************************************************************* - * - * Function BTM_SetInquiryMode - * - * Description This function is called to set standard, with RSSI - * mode or extended of the inquiry for local device. - * - * Input Params: BTM_INQ_RESULT_STANDARD, BTM_INQ_RESULT_WITH_RSSI or - * BTM_INQ_RESULT_EXTENDED - * - * Returns BTM_SUCCESS if successful - * BTM_NO_RESOURCES if couldn't get a memory pool buffer - * BTM_ILLEGAL_VALUE if a bad parameter was detected - * BTM_WRONG_MODE if the device is not up. - * - ******************************************************************************/ -[[nodiscard]] tBTM_STATUS BTM_SetInquiryMode(uint8_t mode); - -void BTM_EnableInterlacedInquiryScan(); - -void BTM_EnableInterlacedPageScan(); - /******************************************************************************* * * Function BTM_ReadRemoteDeviceName diff --git a/system/stack/include/btm_inq.h b/system/stack/include/btm_inq.h index 103fbe56310..40a8f5b29c3 100644 --- a/system/stack/include/btm_inq.h +++ b/system/stack/include/btm_inq.h @@ -38,7 +38,7 @@ * BTM_WRONG_MODE if the device is not up. * ******************************************************************************/ -tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode); +[[nodiscard]] tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode); /******************************************************************************* * @@ -74,8 +74,8 @@ tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode); * BTM_WRONG_MODE if the device is not up. * ******************************************************************************/ -tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, - tBTM_CMPL_CB* p_cmpl_cb); +[[nodiscard]] tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, + tBTM_CMPL_CB* p_cmpl_cb); /******************************************************************************* * @@ -86,7 +86,7 @@ tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb, * Returns Bitmask of current inquiry state * ******************************************************************************/ -uint16_t BTM_IsInquiryActive(void); +[[nodiscard]] uint16_t BTM_IsInquiryActive(void); /******************************************************************************* * @@ -111,7 +111,7 @@ void BTM_CancelInquiry(void); * BTM_WRONG_MODE if the device is not up. * ******************************************************************************/ -tBTM_STATUS BTM_SetConnectability(uint16_t page_mode); +[[nodiscard]] tBTM_STATUS BTM_SetConnectability(uint16_t page_mode); /******************************************************************************* * @@ -129,8 +129,32 @@ tBTM_STATUS BTM_SetConnectability(uint16_t page_mode); * BTM_WRONG_MODE if the device is not up. * ******************************************************************************/ -tBTM_STATUS BTM_SetInquiryMode(uint8_t mode); +[[nodiscard]] tBTM_STATUS BTM_SetInquiryMode(uint8_t mode); +/******************************************************************************* + * + * Function BTM_EnableInterlacedInquiryScan + * + * Description Reads system property PROPERTY_INQ_SCAN_TYPE and + * enables interlaced inquiry scan with controller support. + * + * Input Params: None + * + * Returns void + * + ******************************************************************************/ void BTM_EnableInterlacedInquiryScan(); +/******************************************************************************* + * + * Function BTM_EnableInterlacedPageScan + * + * Description Reads system property PROPERTY_PAGE_SCAN_TYPE and + * enables interlaced page scan with controller support. + * + * Input Params: None + * + * Returns void + * + ******************************************************************************/ void BTM_EnableInterlacedPageScan(); diff --git a/system/stack/test/btm/stack_btm_inq_test.cc b/system/stack/test/btm/stack_btm_inq_test.cc index 5192773858e..c46c9cc1286 100644 --- a/system/stack/test/btm/stack_btm_inq_test.cc +++ b/system/stack/test/btm/stack_btm_inq_test.cc @@ -17,7 +17,6 @@ #include #include #include -#include #include @@ -27,7 +26,7 @@ #include "hci/hci_layer_fake.h" #include "hci/hci_packets.h" #include "stack/btm/btm_int_types.h" -#include "stack/include/btm_api.h" +#include "stack/include/btm_inq.h" #include "stack/include/hci_error_code.h" #include "stack/include/inq_hci_link_interface.h" #include "stack/include/main_thread.h" -- GitLab From d193d09048011d11293225e45a4dfd91b06fbeaf Mon Sep 17 00:00:00 2001 From: Yuyang Huang Date: Tue, 18 Jun 2024 20:26:56 +0000 Subject: [PATCH 0070/1446] Remove use_dsp_codec_when_controller_does_not_support flag This flag was added in 24Q2 to allow the DSP to be used for LC3 when the BT controller does not support it. This is now the default behavior, so the flag is no longer needed. Bug: 347316578 Change-Id: I581d217fa07472152cded36f160b964168735328 Flag: exempt, nextfood flag removal change Test: atest net_test_bta --- flags/hfp.aconfig | 7 ------ system/device/src/esco_parameters.cc | 34 +++++++++++++--------------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/flags/hfp.aconfig b/flags/hfp.aconfig index 45e20865794..80927fbeb8a 100644 --- a/flags/hfp.aconfig +++ b/flags/hfp.aconfig @@ -22,13 +22,6 @@ flag { bug: "308497929" } -flag { - name: "use_dsp_codec_when_controller_does_not_support" - namespace: "bluetooth" - description: "use codec on the DSP when the BT controller does not support it" - bug: "308838380" -} - flag { name: "is_sco_managed_by_audio" namespace: "bluetooth" diff --git a/system/device/src/esco_parameters.cc b/system/device/src/esco_parameters.cc index f571f06ff84..44f6fe98259 100644 --- a/system/device/src/esco_parameters.cc +++ b/system/device/src/esco_parameters.cc @@ -371,24 +371,22 @@ enh_esco_params_t esco_parameters_for_codec(esco_codec_t codec, bool offload) { ESCO_NUM_CODECS); std::vector codecIds; - if (com::android::bluetooth::flags:: - use_dsp_codec_when_controller_does_not_support()) { - auto controller = bluetooth::shim::GetController(); - if (controller == nullptr) { - log::warn("controller is null"); - } else { - codecIds = controller->GetLocalSupportedBrEdrCodecIds(); - if (std::find(codecIds.begin(), codecIds.end(), ESCO_CODING_FORMAT_LC3) == - codecIds.end()) { - if (codec == ESCO_CODEC_LC3_T1 || codec == ESCO_CODEC_LC3_T2) { - log::info("BT controller does not support LC3 codec, use DSP codec"); - enh_esco_params_t param = default_esco_parameters[codec]; - param.input_coding_format.coding_format = ESCO_CODING_FORMAT_LC3; - param.output_coding_format.coding_format = ESCO_CODING_FORMAT_LC3; - param.input_bandwidth = TXRX_64KBITS_RATE; - param.output_bandwidth = TXRX_64KBITS_RATE; - return param; - } + + auto controller = bluetooth::shim::GetController(); + if (controller == nullptr) { + log::warn("controller is null"); + } else { + codecIds = controller->GetLocalSupportedBrEdrCodecIds(); + if (std::find(codecIds.begin(), codecIds.end(), ESCO_CODING_FORMAT_LC3) == + codecIds.end()) { + if (codec == ESCO_CODEC_LC3_T1 || codec == ESCO_CODEC_LC3_T2) { + log::info("BT controller does not support LC3 codec, use DSP codec"); + enh_esco_params_t param = default_esco_parameters[codec]; + param.input_coding_format.coding_format = ESCO_CODING_FORMAT_LC3; + param.output_coding_format.coding_format = ESCO_CODING_FORMAT_LC3; + param.input_bandwidth = TXRX_64KBITS_RATE; + param.output_bandwidth = TXRX_64KBITS_RATE; + return param; } } } -- GitLab From d2ffd559e61b77460208b1061e1c0ae03fd08e97 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Sat, 25 May 2024 08:42:18 -0700 Subject: [PATCH 0071/1446] [12/19] get_btm_client_interface().peer.BTM_ReadRemoteDeviceName Bug: 343772702 Test: m . Flag: EXEMPT, Mechanical Refactor Change-Id: Ic5618ad3c35ebb4075a2fad960b7c98e3de26959 --- system/stack/btm/btm_sec.cc | 16 +++++++++------- system/test/headless/read/name.cc | 11 ++++++----- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/system/stack/btm/btm_sec.cc b/system/stack/btm/btm_sec.cc index a277a2b9722..f799aaecf84 100644 --- a/system/stack/btm/btm_sec.cc +++ b/system/stack/btm/btm_sec.cc @@ -831,7 +831,8 @@ tBTM_STATUS btm_sec_bond_by_transport(const RawAddress& bd_addr, * -> RNR (to learn if peer is 2.1) * RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */ btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_GET_REM_NAME); - status = BTM_ReadRemoteDeviceName(bd_addr, NULL, BT_TRANSPORT_BR_EDR); + status = get_btm_client_interface().peer.BTM_ReadRemoteDeviceName( + bd_addr, NULL, BT_TRANSPORT_BR_EDR); } else { /* We are accepting connection request from peer */ btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_WAIT_PIN_REQ); @@ -2449,8 +2450,9 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, } } else { log::warn("wrong BDA, retry with pairing BDA"); - if (BTM_ReadRemoteDeviceName(btm_sec_cb.pairing_bda, NULL, - BT_TRANSPORT_BR_EDR) != BTM_CMD_STARTED) { + if (get_btm_client_interface().peer.BTM_ReadRemoteDeviceName( + btm_sec_cb.pairing_bda, NULL, BT_TRANSPORT_BR_EDR) != + BTM_CMD_STARTED) { log::error("failed to start remote name request"); NotifyBondingChange(*p_dev_rec, HCI_ERR_MEMORY_FULL); }; @@ -3692,8 +3694,8 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, /* remote device name is unknowm, start getting remote name first */ btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_GET_REM_NAME); - if (BTM_ReadRemoteDeviceName(p_dev_rec->bd_addr, NULL, - BT_TRANSPORT_BR_EDR) != + if (get_btm_client_interface().peer.BTM_ReadRemoteDeviceName( + p_dev_rec->bd_addr, NULL, BT_TRANSPORT_BR_EDR) != BTM_CMD_STARTED) { log::error("cannot read remote name"); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_IDLE); @@ -3727,8 +3729,8 @@ void btm_sec_connected(const RawAddress& bda, uint16_t handle, if (BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4)) { /* Try again: RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */ btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_GET_REM_NAME); - if (BTM_ReadRemoteDeviceName(bda, NULL, BT_TRANSPORT_BR_EDR) != - BTM_CMD_STARTED) { + if (get_btm_client_interface().peer.BTM_ReadRemoteDeviceName( + bda, NULL, BT_TRANSPORT_BR_EDR) != BTM_CMD_STARTED) { log::error("cannot read remote name"); btm_sec_cb.change_pairing_state(BTM_PAIR_STATE_IDLE); } diff --git a/system/test/headless/read/name.cc b/system/test/headless/read/name.cc index bed84bfee2e..0b7b4b40f50 100644 --- a/system/test/headless/read/name.cc +++ b/system/test/headless/read/name.cc @@ -20,9 +20,9 @@ #include -#include "os/log.h" // android log only -#include "stack/include/btm_api.h" -#include "stack/include/btm_api_types.h" +#include "stack/btm/neighbor_inquiry.h" +#include "stack/include/bt_name.h" +#include "stack/include/btm_client_interface.h" #include "test/headless/get_options.h" #include "test/headless/headless.h" #include "types/raw_address.h" @@ -52,8 +52,9 @@ int bluetooth::test::headless::Name::Run() { auto future = promise_.get_future(); - tBTM_STATUS status = BTM_ReadRemoteDeviceName( - raw_address, &RemoteNameCallback, BT_TRANSPORT_BR_EDR); + tBTM_STATUS status = + get_btm_client_interface().peer.BTM_ReadRemoteDeviceName( + raw_address, &RemoteNameCallback, BT_TRANSPORT_BR_EDR); if (status != BTM_CMD_STARTED) { fprintf(stdout, "Failure to start read remote device\n"); return -1; -- GitLab From 20a6173d245ec02518f22857bbcd716aeeeec6eb Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Mon, 17 Jun 2024 19:19:46 -0700 Subject: [PATCH 0072/1446] stack::btm::client_interface Move non-lifecycle APIs from group Bug: 347809395 Test: m . Flag: EXEMPT, Mechanical Refactor Change-Id: I9f877541352842d9a940cbd765c6e27d2d228255 --- system/bta/av/bta_av_aact.cc | 10 +++++----- system/stack/btm/btm_client_interface.cc | 7 +++++-- system/stack/include/btm_client_interface.h | 13 ++++++++----- system/test/mock/mock_stack_btm_interface.cc | 17 ++++++++++------- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/system/bta/av/bta_av_aact.cc b/system/bta/av/bta_av_aact.cc index 3dabb8d17d7..e679b11c0c0 100644 --- a/system/bta/av/bta_av_aact.cc +++ b/system/bta/av/bta_av_aact.cc @@ -3143,8 +3143,8 @@ void bta_av_vendor_offload_start_v2(tBTA_AV_SCB* p_scb, log::verbose(""); uint16_t connection_handle = - get_btm_client_interface().lifecycle.BTM_GetHCIConnHandle( - p_scb->PeerAddress(), BT_TRANSPORT_BR_EDR); + get_btm_client_interface().peer.BTM_GetHCIConnHandle(p_scb->PeerAddress(), + BT_TRANSPORT_BR_EDR); btav_a2dp_scmst_info_t scmst_info = p_scb->p_cos->get_scmst_info(p_scb->PeerAddress()); uint16_t mtu = p_scb->stream_mtu; @@ -3204,7 +3204,7 @@ void bta_av_vendor_offload_stop() { return; } uint16_t connection_handle = - get_btm_client_interface().lifecycle.BTM_GetHCIConnHandle( + get_btm_client_interface().peer.BTM_GetHCIConnHandle( p_scb->PeerAddress(), BT_TRANSPORT_BR_EDR); uint16_t l2cap_channel_handle = 0; @@ -3376,8 +3376,8 @@ static void bta_av_offload_codec_builder(tBTA_AV_SCB* p_scb, p_a2dp_offload->max_latency = 0; p_a2dp_offload->mtu = mtu; p_a2dp_offload->acl_hdl = - get_btm_client_interface().lifecycle.BTM_GetHCIConnHandle( - p_scb->PeerAddress(), BT_TRANSPORT_BR_EDR); + get_btm_client_interface().peer.BTM_GetHCIConnHandle(p_scb->PeerAddress(), + BT_TRANSPORT_BR_EDR); btav_a2dp_scmst_info_t scmst_info = p_scb->p_cos->get_scmst_info(p_scb->PeerAddress()); p_a2dp_offload->scms_t_enable[0] = scmst_info.enable_status; diff --git a/system/stack/btm/btm_client_interface.cc b/system/stack/btm/btm_client_interface.cc index 3db1bd04686..648a51cf893 100644 --- a/system/stack/btm/btm_client_interface.cc +++ b/system/stack/btm/btm_client_interface.cc @@ -27,8 +27,6 @@ struct btm_client_interface_t btm_client_interface = { .lifecycle = { .BTM_PmRegister = ::BTM_PmRegister, - .BTM_GetHCIConnHandle = ::BTM_GetHCIConnHandle, - .BTM_VendorSpecificCommand = ::BTM_VendorSpecificCommand, .ACL_RegisterClient = ::ACL_RegisterClient, .ACL_UnregisterClient = ::ACL_UnregisterClient, .btm_init = ::btm_init, @@ -55,6 +53,7 @@ struct btm_client_interface_t btm_client_interface = { .BTM_RequestPeerSCA = ::BTM_RequestPeerSCA, .BTM_GetPeerSCA = ::BTM_GetPeerSCA, .BTM_IsPhy2mSupported = ::BTM_IsPhy2mSupported, + .BTM_GetHCIConnHandle = ::BTM_GetHCIConnHandle, }, .link_policy = @@ -132,6 +131,10 @@ struct btm_client_interface_t btm_client_interface = { .BTM_InqDbNext = ::BTM_InqDbNext, .BTM_ClearInqDb = ::BTM_ClearInqDb, }, + .vendor = + { + .BTM_VendorSpecificCommand = ::BTM_VendorSpecificCommand, + }, }; struct btm_client_interface_t& get_btm_client_interface() { diff --git a/system/stack/include/btm_client_interface.h b/system/stack/include/btm_client_interface.h index bed8ce6df31..ae5c01267d5 100644 --- a/system/stack/include/btm_client_interface.h +++ b/system/stack/include/btm_client_interface.h @@ -35,11 +35,6 @@ struct btm_client_interface_t { struct { [[nodiscard]] tBTM_STATUS (*BTM_PmRegister)(uint8_t mask, uint8_t* p_pm_id, tBTM_PM_STATUS_CBACK* p_cback); - [[nodiscard]] uint16_t (*BTM_GetHCIConnHandle)(const RawAddress& bd_addr, - tBT_TRANSPORT transport); - void (*BTM_VendorSpecificCommand)(uint16_t opcode, uint8_t param_len, - uint8_t* p_param_buf, - tBTM_VSC_CMPL_CB* p_cb); void (*ACL_RegisterClient)(struct acl_client_callback_s* callbacks); void (*ACL_UnregisterClient)(struct acl_client_callback_s* callbacks); void (*btm_init)(); @@ -76,6 +71,8 @@ struct btm_client_interface_t { tBT_TRANSPORT transport); [[nodiscard]] bool (*BTM_IsPhy2mSupported)(const RawAddress& remote_bda, tBT_TRANSPORT transport); + [[nodiscard]] uint16_t (*BTM_GetHCIConnHandle)(const RawAddress& bd_addr, + tBT_TRANSPORT transport); } peer; struct { @@ -176,6 +173,12 @@ struct btm_client_interface_t { [[nodiscard]] tBTM_INQ_INFO* (*BTM_InqDbNext)(tBTM_INQ_INFO* p_cur); [[nodiscard]] tBTM_STATUS (*BTM_ClearInqDb)(const RawAddress* p_bda); } db; + + struct { + void (*BTM_VendorSpecificCommand)(uint16_t opcode, uint8_t param_len, + uint8_t* p_param_buf, + tBTM_VSC_CMPL_CB* p_cb); + } vendor; }; struct btm_client_interface_t& get_btm_client_interface(); diff --git a/system/test/mock/mock_stack_btm_interface.cc b/system/test/mock/mock_stack_btm_interface.cc index dcd45922e61..8fd90818704 100644 --- a/system/test/mock/mock_stack_btm_interface.cc +++ b/system/test/mock/mock_stack_btm_interface.cc @@ -37,13 +37,6 @@ struct btm_client_interface_t default_btm_client_interface = { tBTM_PM_STATUS_CBACK* /* p_cb */) -> tBTM_STATUS { return BTM_SUCCESS; }, - .BTM_GetHCIConnHandle = [](const RawAddress& /* remote_bda */, - tBT_TRANSPORT /* transport */) -> uint16_t { - return 0; - }, - .BTM_VendorSpecificCommand = - [](uint16_t /* opcode */, uint8_t /* param_len */, - uint8_t* /* p_param_buf */, tBTM_VSC_CMPL_CB* /* p_cb */) {}, .ACL_RegisterClient = [](struct acl_client_callback_s* /* callbacks */) {}, .ACL_UnregisterClient = @@ -81,6 +74,10 @@ struct btm_client_interface_t default_btm_client_interface = { [](const RawAddress& /* addr */, uint8_t* /* lmp_version */, uint16_t* /* manufacturer */, uint16_t* /* lmp_sub_version */) -> bool { return false; }, + .BTM_GetHCIConnHandle = [](const RawAddress& /* remote_bda */, + tBT_TRANSPORT /* transport */) -> uint16_t { + return 0; + }, }, .link_policy = { .BTM_GetRole = [](const RawAddress& /* remote_bd_addr */, @@ -291,6 +288,12 @@ struct btm_client_interface_t default_btm_client_interface = { return BTM_SUCCESS; }, }, + .vendor = + { + .BTM_VendorSpecificCommand = + [](uint16_t /* opcode */, uint8_t /* param_len */, + uint8_t* /* p_param_buf */, tBTM_VSC_CMPL_CB* /* p_cb */) {}, + }, }; } // namespace -- GitLab From e97b4c2b162662a779d6592b557bcefa2f12e1ad Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Thu, 13 Jun 2024 18:05:54 -0700 Subject: [PATCH 0073/1446] stack::hci HCI_RMT_NAME_REQUEST command status handled by gd rnr module Bug: 347285659 Test: m . Flag: EXEMPT, Code Removal Change-Id: If10dff09790ce951b05ae0bd8bdb7343cda8a5be --- system/stack/btu/btu_hcif.cc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/system/stack/btu/btu_hcif.cc b/system/stack/btu/btu_hcif.cc index f9a794527ca..cf8b3a542af 100644 --- a/system/stack/btu/btu_hcif.cc +++ b/system/stack/btu/btu_hcif.cc @@ -1096,13 +1096,6 @@ static void btu_hcif_hdl_command_status(uint16_t opcode, uint8_t status, btm_sec_encrypt_change(HCI_INVALID_HANDLE, hci_status, false); } break; - case HCI_RMT_NAME_REQUEST: - if (status != HCI_SUCCESS) { - // Tell inquiry processing that we are done - btm_process_remote_name(nullptr, nullptr, 0, hci_status); - btm_sec_rmt_name_request_complete(nullptr, nullptr, hci_status); - } - break; case HCI_READ_RMT_EXT_FEATURES: if (status != HCI_SUCCESS) { STREAM_TO_UINT16(handle, p_cmd); -- GitLab From c9f07879c6e0a1beb26ffeed2ac2c4eae489f2c0 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Sat, 25 May 2024 08:54:45 -0700 Subject: [PATCH 0074/1446] [14/19] get_btm_client_interface().peer.BTM_ReadRemoteVersion Bug: 343772702 Test: m . Flag: EXEMPT, Mechanical Refactor Change-Id: I5a715234b17c2ce5f98b197a92854100dab6cb8b --- system/bta/gatt/bta_gattc_cache.cc | 10 +++++----- system/btif/src/btif_bqr.cc | 5 +++-- system/btif/src/btif_dm.cc | 3 ++- system/btif/src/btif_iot_config.cc | 7 +++---- system/stack/btm/btm_ble_sec.cc | 6 +++--- system/stack/smp/smp_act.cc | 6 +++--- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/system/bta/gatt/bta_gattc_cache.cc b/system/bta/gatt/bta_gattc_cache.cc index 6230e36db86..9a86ed0538e 100644 --- a/system/bta/gatt/bta_gattc_cache.cc +++ b/system/bta/gatt/bta_gattc_cache.cc @@ -36,15 +36,13 @@ #include "bta/gatt/bta_gattc_int.h" #include "bta/gatt/database.h" -#include "common/init_flags.h" #include "device/include/interop.h" #include "internal_include/bt_target.h" -#include "internal_include/bt_trace.h" -#include "os/log.h" #include "osi/include/allocator.h" #include "stack/btm/btm_sec.h" #include "stack/include/bt_types.h" #include "stack/include/bt_uuid16.h" +#include "stack/include/btm_client_interface.h" #include "stack/include/gatt_api.h" #include "stack/include/sdp_api.h" #include "types/bluetooth/uuid.h" @@ -164,7 +162,8 @@ RobustCachingSupport GetRobustCachingSupport(const tBTA_GATTC_CLCB* p_clcb, } if (p_clcb->transport == BT_TRANSPORT_LE && - !BTM_IsRemoteVersionReceived(p_clcb->bda)) { + !get_btm_client_interface().ble.BTM_IsRemoteVersionReceived( + p_clcb->bda)) { log::info("version info is not ready yet"); return RobustCachingSupport::W4_REMOTE_VERSION; } @@ -175,7 +174,8 @@ RobustCachingSupport GetRobustCachingSupport(const tBTA_GATTC_CLCB* p_clcb, // embedded device having LMP version lower than 5.1 (0x0a), it does not // support GATT Caching. uint8_t lmp_version = 0; - if (!BTM_ReadRemoteVersion(p_clcb->bda, &lmp_version, nullptr, nullptr)) { + if (!get_btm_client_interface().peer.BTM_ReadRemoteVersion( + p_clcb->bda, &lmp_version, nullptr, nullptr)) { log::warn("Could not read remote version for {}", p_clcb->bda); } diff --git a/system/btif/src/btif_bqr.cc b/system/btif/src/btif_bqr.cc index 5b8da06d955..25efd5df4ce 100644 --- a/system/btif/src/btif_bqr.cc +++ b/system/btif/src/btif_bqr.cc @@ -43,6 +43,7 @@ #include "stack/include/bt_types.h" #include "stack/include/btm_api.h" #include "stack/include/btm_ble_api.h" +#include "stack/include/btm_client_interface.h" namespace bluetooth { namespace bqr { @@ -849,8 +850,8 @@ static void btif_get_remote_version(const RawAddress& bd_addr, uint16_t tmp_lmp_subver = 0; tBTM_STATUS status; - status = BTM_ReadRemoteVersion(bd_addr, &tmp_lmp_ver, &tmp_manufacturer, - &tmp_lmp_subver); + status = get_btm_client_interface().peer.BTM_ReadRemoteVersion( + bd_addr, &tmp_lmp_ver, &tmp_manufacturer, &tmp_lmp_subver); if (status == BTM_SUCCESS && (tmp_lmp_ver || tmp_manufacturer || tmp_lmp_subver)) { lmp_version = tmp_lmp_ver; diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index 7fe33e30977..b05fcb09a5a 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -665,7 +665,8 @@ static void btif_update_remote_version_property(RawAddress* p_bd) { log::assert_that(p_bd != nullptr, "assert failed: p_bd != nullptr"); const bool version_info_valid = - BTM_ReadRemoteVersion(*p_bd, &lmp_ver, &mfct_set, &lmp_subver); + get_btm_client_interface().peer.BTM_ReadRemoteVersion( + *p_bd, &lmp_ver, &mfct_set, &lmp_subver); log::info("Remote version info valid:{} [{}]:0x{:x},0x{:x},0x{:x}", version_info_valid, *p_bd, lmp_ver, mfct_set, lmp_subver); diff --git a/system/btif/src/btif_iot_config.cc b/system/btif/src/btif_iot_config.cc index 08fde4a7fc3..d96d900ebb4 100644 --- a/system/btif/src/btif_iot_config.cc +++ b/system/btif/src/btif_iot_config.cc @@ -21,9 +21,8 @@ #include "bta_sec_api.h" #include "btif_storage.h" #include "device/include/device_iot_config.h" -#include "internal_include/bt_target.h" -#include "os/log.h" #include "stack/include/btm_ble_api.h" +#include "stack/include/btm_client_interface.h" using namespace bluetooth; @@ -135,8 +134,8 @@ void btif_iot_update_remote_info(tBTA_DM_AUTH_CMPL* p_auth_cmpl, bool is_ble, (int)p_auth_cmpl->addr_type); // save remote versions to iot conf file - btm_status = BTM_ReadRemoteVersion(p_auth_cmpl->bd_addr, &lmp_ver, &mfct_set, - &lmp_subver); + btm_status = get_btm_client_interface().peer.BTM_ReadRemoteVersion( + p_auth_cmpl->bd_addr, &lmp_ver, &mfct_set, &lmp_subver); if (btm_status == BTM_SUCCESS) { DEVICE_IOT_CONFIG_ADDR_SET_INT(p_auth_cmpl->bd_addr, diff --git a/system/stack/btm/btm_ble_sec.cc b/system/stack/btm/btm_ble_sec.cc index 7f647cabb07..f753b04ea48 100644 --- a/system/stack/btm/btm_ble_sec.cc +++ b/system/stack/btm/btm_ble_sec.cc @@ -33,7 +33,6 @@ #include "device/include/interop_config.h" #include "hci/controller_interface.h" #include "main/shim/entry.h" -#include "os/log.h" #include "osi/include/allocator.h" #include "osi/include/properties.h" #include "platform_ssl_mem.h" @@ -53,6 +52,7 @@ #include "stack/include/btm_ble_addr.h" #include "stack/include/btm_ble_privacy.h" #include "stack/include/btm_ble_sec_api.h" +#include "stack/include/btm_client_interface.h" #include "stack/include/btm_log_history.h" #include "stack/include/btm_status.h" #include "stack/include/gatt_api.h" @@ -1272,8 +1272,8 @@ static void btm_ble_notify_enc_cmpl(const RawAddress& bd_addr, bool encr_enable) { if (encr_enable) { uint8_t remote_lmp_version = 0; - if (!BTM_ReadRemoteVersion(bd_addr, &remote_lmp_version, nullptr, - nullptr) || + if (!get_btm_client_interface().peer.BTM_ReadRemoteVersion( + bd_addr, &remote_lmp_version, nullptr, nullptr) || remote_lmp_version == 0) { log::warn("BLE Unable to determine remote version"); } diff --git a/system/stack/smp/smp_act.cc b/system/stack/smp/smp_act.cc index 3de985dfaab..f9c15800390 100644 --- a/system/stack/smp/smp_act.cc +++ b/system/stack/smp/smp_act.cc @@ -36,7 +36,7 @@ #include "stack/btm/btm_sec.h" #include "stack/include/bt_octets.h" #include "stack/include/bt_types.h" -#include "stack/include/btm_api.h" +#include "stack/include/btm_client_interface.h" #include "stack/include/btm_log_history.h" #include "stack/include/smp_api_types.h" #include "types/raw_address.h" @@ -191,8 +191,8 @@ void smp_send_app_cback(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { p_cb->loc_auth_req |= SMP_SC_SUPPORT_BIT; } - if (!BTM_ReadRemoteVersion(p_cb->pairing_bda, &remote_lmp_version, - nullptr, nullptr)) { + if (!get_btm_client_interface().peer.BTM_ReadRemoteVersion( + p_cb->pairing_bda, &remote_lmp_version, nullptr, nullptr)) { log::warn("SMP Unable to determine remote_lmp_version:{}", remote_lmp_version); } -- GitLab From 97f9ad870dc74d187b6e22a5ef2280fe14288242 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Mon, 17 Jun 2024 17:10:05 -0700 Subject: [PATCH 0075/1446] stack::sdp::tSDP_STATE Use proper type Bug: 347806116 Test: m . Flag: EXEMPT, Mechanical Refactor Change-Id: I80ad311c65bd66cc985c3cc55242387b7d0bb19e --- system/stack/sdp/sdpint.h | 2 +- system/stack/test/sdp/stack_sdp_test.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/stack/sdp/sdpint.h b/system/stack/sdp/sdpint.h index bb611869042..3b1cbb02dbf 100644 --- a/system/stack/sdp/sdpint.h +++ b/system/stack/sdp/sdpint.h @@ -178,7 +178,7 @@ typedef uint8_t tSDP_DISC_WAIT; /* Define the SDP Connection Control Block */ struct tCONN_CB { - uint8_t con_state; + tSDP_STATE con_state; uint8_t con_flags; RawAddress device_address; diff --git a/system/stack/test/sdp/stack_sdp_test.cc b/system/stack/test/sdp/stack_sdp_test.cc index ffbf325b8ed..4f56618afd4 100644 --- a/system/stack/test/sdp/stack_sdp_test.cc +++ b/system/stack/test/sdp/stack_sdp_test.cc @@ -112,7 +112,7 @@ TEST_F(StackSdpInitTest, sdp_service_search_request) { ASSERT_EQ(p_ccb->con_state, SDP_STATE_IDLE); } -tCONN_CB* find_ccb(uint16_t cid, uint8_t state) { +tCONN_CB* find_ccb(uint16_t cid, tSDP_STATE state) { uint16_t xx; tCONN_CB* p_ccb; -- GitLab From 5df466a6c9eb63232fa57b91d674d134f3488da1 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Tue, 4 Jun 2024 15:29:49 -0700 Subject: [PATCH 0076/1446] Streamline enum stack::l2cap::tL2CAP_DW_RESULT Bug: 344992630 Test: m . Flag: EXEMPT, Mechanical Refactor Change-Id: I58c45c5c40e155e0e4c5b6bb3bc50333ca798037 --- system/main/shim/l2c_api.h | 10 +++--- system/stack/arbiter/acl_arbiter.cc | 2 +- system/stack/avct/avct_bcb_act.cc | 6 ++-- system/stack/avct/avct_lcb_act.cc | 7 ++-- system/stack/bnep/bnep_main.cc | 3 +- system/stack/bnep/bnep_utils.cc | 3 +- system/stack/fuzzers/avrc_fuzzer.cc | 2 +- system/stack/fuzzers/bnep_fuzzer.cc | 2 +- system/stack/fuzzers/gatt_fuzzer.cc | 4 +-- system/stack/fuzzers/sdp_fuzzer.cc | 2 +- system/stack/fuzzers/smp_fuzzer.cc | 2 +- system/stack/gap/gap_conn.cc | 4 +-- system/stack/gatt/att_protocol.cc | 4 +-- system/stack/hid/hidd_conn.cc | 4 +-- system/stack/hid/hidh_conn.cc | 2 +- system/stack/include/l2c_api.h | 6 ++-- system/stack/l2cap/l2c_api.cc | 16 ++++----- system/stack/l2cap/l2c_main.cc | 10 +++--- system/stack/rfcomm/rfc_ts_frames.cc | 3 +- system/stack/rfcomm/rfc_utils.cc | 2 +- system/stack/sdp/sdp_discovery.cc | 6 ++-- system/stack/sdp/sdp_server.cc | 6 ++-- system/stack/sdp/sdp_utils.cc | 2 +- system/stack/smp/smp_utils.cc | 4 +-- system/stack/test/rfcomm/stack_rfcomm_test.cc | 36 +++++++++---------- system/stack/test/sdp/stack_sdp_parse_test.cc | 2 +- system/stack/test/sdp/stack_sdp_test.cc | 2 +- system/stack/test/sdp/stack_sdp_utils_test.cc | 2 +- system/test/mock/mock_stack_l2cap_api.h | 6 ++-- system/test/mock/mock_stack_l2cap_main.cc | 2 +- 30 files changed, 78 insertions(+), 84 deletions(-) diff --git a/system/main/shim/l2c_api.h b/system/main/shim/l2c_api.h index 7f359cafef7..d668d175ff9 100644 --- a/system/main/shim/l2c_api.h +++ b/system/main/shim/l2c_api.h @@ -216,11 +216,11 @@ bool L2CA_DisconnectLECocReq(uint16_t cid); * * Description Higher layers call this function to write data. * - * Returns tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS, if data accepted, else + * Returns tL2CAP_DW_RESULT::SUCCESS, if data accepted, else * false - * tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED, if data accepted + * tL2CAP_DW_RESULT::CONGESTED, if data accepted * and the channel is congested - * tL2CAP_DW_RESULT::L2CAP_DW_FAILED, if error + * tL2CAP_DW_RESULT::FAILED, if error * ******************************************************************************/ uint8_t L2CA_DataWrite(uint16_t cid, BT_HDR* p_data); @@ -355,8 +355,8 @@ bool L2CA_ConnectFixedChnl(uint16_t fixed_cid, const RawAddress& bd_addr); * BD Address of remote * Pointer to buffer of type BT_HDR * - * Return value tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS, if data accepted - * tL2CAP_DW_RESULT::L2CAP_DW_FAILED, if error + * Return value tL2CAP_DW_RESULT::SUCCESS, if data accepted + * tL2CAP_DW_RESULT::FAILED, if error * ******************************************************************************/ uint16_t L2CA_SendFixedChnlData(uint16_t fixed_cid, const RawAddress& rem_bda, diff --git a/system/stack/arbiter/acl_arbiter.cc b/system/stack/arbiter/acl_arbiter.cc index c7f43271cc7..c2fc1c04ba0 100644 --- a/system/stack/arbiter/acl_arbiter.cc +++ b/system/stack/arbiter/acl_arbiter.cc @@ -117,7 +117,7 @@ void AclArbiter::SendPacketToPeer(uint8_t tcb_idx, p_buf->offset = L2CAP_MIN_OFFSET; p_buf->len = buffer.size(); if (L2CA_SendFixedChnlData(L2CAP_ATT_CID, p_tcb->peer_bda, p_buf) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to send L2CAP data peer:{} fixed_cid:{} len:{}", p_tcb->peer_bda, L2CAP_ATT_CID, p_buf->len); } diff --git a/system/stack/avct/avct_bcb_act.cc b/system/stack/avct/avct_bcb_act.cc index 2ef6eb41240..853d3b66389 100644 --- a/system/stack/avct/avct_bcb_act.cc +++ b/system/stack/avct/avct_bcb_act.cc @@ -476,8 +476,7 @@ void avct_bcb_send_msg(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) { p_buf->layer_specific = AVCT_DATA_BROWSE; /* send message to L2CAP */ - if (L2CA_DataWrite(p_bcb->ch_lcid, p_buf) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + if (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); } @@ -583,8 +582,7 @@ void avct_bcb_msg_ind(tAVCT_BCB* p_bcb, tAVCT_LCB_EVT* p_data) { AVCT_BUILD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ); UINT16_TO_BE_STREAM(p, pid); p_buf->layer_specific = AVCT_DATA_BROWSE; - if (L2CA_DataWrite(p_bcb->ch_lcid, p_buf) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + if (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); } diff --git a/system/stack/avct/avct_lcb_act.cc b/system/stack/avct/avct_lcb_act.cc index 981f9cc9ec0..1f38cfeb9b3 100644 --- a/system/stack/avct/avct_lcb_act.cc +++ b/system/stack/avct/avct_lcb_act.cc @@ -508,7 +508,7 @@ void avct_lcb_cong_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { while (!p_lcb->cong && (p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_lcb->tx_q)) != NULL) { if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == - tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED) { + tL2CAP_DW_RESULT::CONGESTED) { p_lcb->cong = true; } } @@ -621,7 +621,7 @@ void avct_lcb_send_msg(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { /* send message to L2CAP */ else { if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == - tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED) { + tL2CAP_DW_RESULT::CONGESTED) { p_lcb->cong = true; } } @@ -725,8 +725,7 @@ void avct_lcb_msg_ind(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* p_data) { p = (uint8_t*)(p_buf + 1) + p_buf->offset; AVCT_BUILD_HDR(p, label, AVCT_PKT_TYPE_SINGLE, AVCT_REJ); UINT16_TO_BE_STREAM(p, pid); - if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + if (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, p_lcb->ch_lcid, p_buf->len); } diff --git a/system/stack/bnep/bnep_main.cc b/system/stack/bnep/bnep_main.cc index 1a269d9228b..7572d2d13d8 100644 --- a/system/stack/bnep/bnep_main.cc +++ b/system/stack/bnep/bnep_main.cc @@ -304,8 +304,7 @@ static void bnep_congestion_ind(uint16_t l2cap_cid, bool is_congested) { if (!p_buf) break; - if (L2CA_DataWrite(l2cap_cid, p_buf) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(l2cap_cid, p_buf) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_bcb->rem_bda, l2cap_cid, p_buf->len); } diff --git a/system/stack/bnep/bnep_utils.cc b/system/stack/bnep/bnep_utils.cc index 113937c4930..f1ccfc1d3b3 100644 --- a/system/stack/bnep/bnep_utils.cc +++ b/system/stack/bnep/bnep_utils.cc @@ -415,8 +415,7 @@ void bnepu_check_send_packet(tBNEP_CONN* p_bcb, BT_HDR* p_buf) { fixed_queue_enqueue(p_bcb->xmit_q, p_buf); } } else { - if (L2CA_DataWrite(p_bcb->l2cap_cid, p_buf) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_bcb->l2cap_cid, p_buf) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_bcb->rem_bda, p_bcb->l2cap_cid, p_buf->len); } diff --git a/system/stack/fuzzers/avrc_fuzzer.cc b/system/stack/fuzzers/avrc_fuzzer.cc index 387e427f13d..69c58bcc4b3 100644 --- a/system/stack/fuzzers/avrc_fuzzer.cc +++ b/system/stack/fuzzers/avrc_fuzzer.cc @@ -62,7 +62,7 @@ class FakeBtStack { log::assert_that(cid == kDummyCid, "assert failed: cid == kDummyCid"); ConsumeData((const uint8_t*)hdr, hdr->offset + hdr->len); osi_free(hdr); - return tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS; + return tL2CAP_DW_RESULT::SUCCESS; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t cid) { log::assert_that(cid == kDummyCid, "assert failed: cid == kDummyCid"); diff --git a/system/stack/fuzzers/bnep_fuzzer.cc b/system/stack/fuzzers/bnep_fuzzer.cc index e7f396d71f1..34ec0fb1182 100644 --- a/system/stack/fuzzers/bnep_fuzzer.cc +++ b/system/stack/fuzzers/bnep_fuzzer.cc @@ -56,7 +56,7 @@ class FakeBtStack { bluetooth::log::assert_that(cid == kDummyCid, "assert failed: cid == kDummyCid"); osi_free(p_data); - return tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS; + return tL2CAP_DW_RESULT::SUCCESS; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t cid) { bluetooth::log::assert_that(cid == kDummyCid, diff --git a/system/stack/fuzzers/gatt_fuzzer.cc b/system/stack/fuzzers/gatt_fuzzer.cc index 63a086443d6..a5a1c6aa96c 100644 --- a/system/stack/fuzzers/gatt_fuzzer.cc +++ b/system/stack/fuzzers/gatt_fuzzer.cc @@ -86,7 +86,7 @@ class FakeBtStack { test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t lcid, BT_HDR* hdr) { osi_free(hdr); - return tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS; + return tL2CAP_DW_RESULT::SUCCESS; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t) { return true; @@ -94,7 +94,7 @@ class FakeBtStack { test::mock::stack_l2cap_api::L2CA_SendFixedChnlData.body = [](uint16_t cid, const RawAddress& addr, BT_HDR* hdr) { osi_free(hdr); - return tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS; + return tL2CAP_DW_RESULT::SUCCESS; }; test::mock::stack_l2cap_api::L2CA_RegisterFixedChannel.body = [](uint16_t fixed_cid, tL2CAP_FIXED_CHNL_REG* p_freg) { diff --git a/system/stack/fuzzers/sdp_fuzzer.cc b/system/stack/fuzzers/sdp_fuzzer.cc index 9a03b5b28f6..4d607aa350b 100644 --- a/system/stack/fuzzers/sdp_fuzzer.cc +++ b/system/stack/fuzzers/sdp_fuzzer.cc @@ -91,7 +91,7 @@ class FakeL2cap { [](uint16_t cid, BT_HDR* p_data) -> tL2CAP_DW_RESULT { auto len = p_data->len; osi_free(p_data); - return tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS; + return tL2CAP_DW_RESULT::SUCCESS; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t lcid) { return true; diff --git a/system/stack/fuzzers/smp_fuzzer.cc b/system/stack/fuzzers/smp_fuzzer.cc index 31e030c2496..96302f408a1 100644 --- a/system/stack/fuzzers/smp_fuzzer.cc +++ b/system/stack/fuzzers/smp_fuzzer.cc @@ -94,7 +94,7 @@ class FakeBtStack { test::mock::stack_l2cap_api::L2CA_SendFixedChnlData.body = [](uint16_t cid, const RawAddress& addr, BT_HDR* hdr) { osi_free(hdr); - return tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS; + return tL2CAP_DW_RESULT::SUCCESS; }; test::mock::stack_l2cap_api::L2CA_RegisterFixedChannel.body = [](uint16_t fixed_cid, tL2CAP_FIXED_CHNL_REG* p_freg) { diff --git a/system/stack/gap/gap_conn.cc b/system/stack/gap/gap_conn.cc index 8e379c4c167..fd434792528 100644 --- a/system/stack/gap/gap_conn.cc +++ b/system/stack/gap/gap_conn.cc @@ -441,10 +441,10 @@ static bool gap_try_write_queued_data(tGAP_CCB* p_ccb) { status = L2CA_DataWrite(p_ccb->connection_id, p_buf); } - if (status == tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED) { + if (status == tL2CAP_DW_RESULT::CONGESTED) { p_ccb->is_congested = true; return true; - } else if (status != tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) + } else if (status != tL2CAP_DW_RESULT::SUCCESS) return false; } return true; diff --git a/system/stack/gatt/att_protocol.cc b/system/stack/gatt/att_protocol.cc index 4294c149b77..f1892128bfd 100644 --- a/system/stack/gatt/att_protocol.cc +++ b/system/stack/gatt/att_protocol.cc @@ -383,10 +383,10 @@ tGATT_STATUS attp_send_msg_to_l2cap(tGATT_TCB& tcb, uint16_t lcid, l2cap_ret = L2CA_DataWrite(lcid, p_toL2CAP); } - if (l2cap_ret == tL2CAP_DW_RESULT::L2CAP_DW_FAILED) { + if (l2cap_ret == tL2CAP_DW_RESULT::FAILED) { log::error("failed to write data to L2CAP"); return GATT_INTERNAL_ERROR; - } else if (l2cap_ret == tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED) { + } else if (l2cap_ret == tL2CAP_DW_RESULT::CONGESTED) { log::verbose("ATT congested, message accepted"); return GATT_CONGESTED; } diff --git a/system/stack/hid/hidd_conn.cc b/system/stack/hid/hidd_conn.cc index 95fce1df1eb..1b96262d7a3 100644 --- a/system/stack/hid/hidd_conn.cc +++ b/system/stack/hid/hidd_conn.cc @@ -89,7 +89,7 @@ static void hidd_check_config_done() { // send outstanding data on intr if (hd_cb.pending_data) { if (L2CA_DataWrite(p_hcon->intr_cid, hd_cb.pending_data) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data cid:{} len:{}", p_hcon->intr_cid, hd_cb.pending_data->len); } @@ -822,7 +822,7 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, log::verbose("report sent"); - if (L2CA_DataWrite(cid, p_buf) == tL2CAP_DW_RESULT::L2CAP_DW_FAILED) { + if (L2CA_DataWrite(cid, p_buf) == tL2CAP_DW_RESULT::FAILED) { log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDD_ERR_CONGESTED_AT_DATA_WRITE, 1); diff --git a/system/stack/hid/hidh_conn.cc b/system/stack/hid/hidh_conn.cc index 3e8699be1bc..d4d3de523d3 100644 --- a/system/stack/hid/hidh_conn.cc +++ b/system/stack/hid/hidh_conn.cc @@ -848,7 +848,7 @@ tHID_STATUS hidh_conn_snd_data(uint8_t dhandle, uint8_t trans_type, /* Send the buffer through L2CAP */ if ((p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) || - (L2CA_DataWrite(cid, p_buf) == tL2CAP_DW_RESULT::L2CAP_DW_FAILED)) { + (L2CA_DataWrite(cid, p_buf) == tL2CAP_DW_RESULT::FAILED)) { log_counter_metrics(android::bluetooth::CodePathCounterKeyEnum:: HIDH_ERR_CONGESTED_AT_SEND_DATA, 1); diff --git a/system/stack/include/l2c_api.h b/system/stack/include/l2c_api.h index ed45627fbae..d02f77367f2 100644 --- a/system/stack/include/l2c_api.h +++ b/system/stack/include/l2c_api.h @@ -53,9 +53,9 @@ /* result code for L2CA_DataWrite() */ enum class tL2CAP_DW_RESULT : uint8_t { - L2CAP_DW_FAILED = 0, - L2CAP_DW_SUCCESS = 1, - L2CAP_DW_CONGESTED = 2, + FAILED = 0, + SUCCESS = 1, + CONGESTED = 2, }; /* Values for priority parameter to L2CA_SetAclPriority */ diff --git a/system/stack/l2cap/l2c_api.cc b/system/stack/l2cap/l2c_api.cc index 0befad885c0..c16e23e7c3d 100644 --- a/system/stack/l2cap/l2c_api.cc +++ b/system/stack/l2cap/l2c_api.cc @@ -1302,13 +1302,13 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, NULL)) { log::warn("No service registered or invalid CID: 0x{:04x}", fixed_cid); osi_free(p_buf); - return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::FAILED); } if (!BTM_IsDeviceUp()) { log::warn("Controller is not ready CID: 0x{:04x}", fixed_cid); osi_free(p_buf); - return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::FAILED); } p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, transport); @@ -1317,7 +1317,7 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, log::warn("Link is disconnecting or does not exist CID: 0x{:04x}", fixed_cid); osi_free(p_buf); - return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::FAILED); } tL2C_BLE_FIXED_CHNLS_MASK peer_channel_mask; @@ -1331,7 +1331,7 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, if ((peer_channel_mask & (1 << fixed_cid)) == 0) { log::warn("Peer does not support fixed channel CID: 0x{:04x}", fixed_cid); osi_free(p_buf); - return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::FAILED); } p_buf->event = 0; @@ -1341,7 +1341,7 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, if (!l2cu_initialize_fixed_ccb(p_lcb, fixed_cid)) { log::warn("No channel control block found for CID: 0x{:4x}", fixed_cid); osi_free(p_buf); - return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::FAILED); } } @@ -1355,7 +1355,7 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, ->xmit_hold_q), p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->buff_quota); osi_free(p_buf); - return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::FAILED); } log::debug("Enqueued data for CID: 0x{:04x} len:{}", fixed_cid, p_buf->len); @@ -1373,10 +1373,10 @@ tL2CAP_DW_RESULT L2CA_SendFixedChnlData(uint16_t fixed_cid, if (p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL]->cong_sent) { log::debug("Link congested for CID: 0x{:04x}", fixed_cid); - return (tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED); + return (tL2CAP_DW_RESULT::CONGESTED); } - return (tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS); + return (tL2CAP_DW_RESULT::SUCCESS); } /******************************************************************************* diff --git a/system/stack/l2cap/l2c_main.cc b/system/stack/l2cap/l2c_main.cc index 7fe9ec19316..ba851c38d5e 100644 --- a/system/stack/l2cap/l2c_main.cc +++ b/system/stack/l2cap/l2c_main.cc @@ -913,7 +913,7 @@ tL2CAP_DW_RESULT l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flags) { if (!p_ccb) { log::warn("L2CAP - no CCB for L2CA_DataWrite, CID: {}", cid); osi_free(p_data); - return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::FAILED); } /* Sending message bigger than mtu size of peer is a violation of protocol */ @@ -930,7 +930,7 @@ tL2CAP_DW_RESULT l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flags) { "size: len={} mtu={}", cid, p_data->len, mtu); osi_free(p_data); - return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::FAILED); } /* channel based, packet based flushable or non-flushable */ @@ -945,12 +945,12 @@ tL2CAP_DW_RESULT l2c_data_write(uint16_t cid, BT_HDR* p_data, uint16_t flags) { p_ccb->buff_quota); osi_free(p_data); - return (tL2CAP_DW_RESULT::L2CAP_DW_FAILED); + return (tL2CAP_DW_RESULT::FAILED); } l2c_csm_execute(p_ccb, L2CEVT_L2CA_DATA_WRITE, p_data); - if (p_ccb->cong_sent) return (tL2CAP_DW_RESULT::L2CAP_DW_CONGESTED); + if (p_ccb->cong_sent) return (tL2CAP_DW_RESULT::CONGESTED); - return (tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS); + return (tL2CAP_DW_RESULT::SUCCESS); } diff --git a/system/stack/rfcomm/rfc_ts_frames.cc b/system/stack/rfcomm/rfc_ts_frames.cc index acc756c5840..068dd022d6c 100644 --- a/system/stack/rfcomm/rfc_ts_frames.cc +++ b/system/stack/rfcomm/rfc_ts_frames.cc @@ -201,8 +201,7 @@ void rfc_send_buf_uih(tRFC_MCB* p_mcb, uint8_t dlci, BT_HDR* p_buf) { if (dlci == RFCOMM_MX_DLCI) { rfc_check_send_cmd(p_mcb, p_buf); } else { - if (L2CA_DataWrite(p_mcb->lcid, p_buf) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_mcb->lcid, p_buf) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_mcb->bd_addr, p_mcb->lcid, p_buf->len); } diff --git a/system/stack/rfcomm/rfc_utils.cc b/system/stack/rfcomm/rfc_utils.cc index 0a3214400f3..06da90fb13f 100644 --- a/system/stack/rfcomm/rfc_utils.cc +++ b/system/stack/rfcomm/rfc_utils.cc @@ -426,7 +426,7 @@ void rfc_check_send_cmd(tRFC_MCB* p_mcb, BT_HDR* p_buf) { while (!p_mcb->l2cap_congested) { BT_HDR* p = (BT_HDR*)fixed_queue_try_dequeue(p_mcb->cmd_q); if (p == NULL) break; - if (L2CA_DataWrite(p_mcb->lcid, p) != tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + if (L2CA_DataWrite(p_mcb->lcid, p) != tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_mcb->bd_addr, p_mcb->lcid, p->len); } diff --git a/system/stack/sdp/sdp_discovery.cc b/system/stack/sdp/sdp_discovery.cc index 11c8f389f5f..b8dbaf832f7 100644 --- a/system/stack/sdp/sdp_discovery.cc +++ b/system/stack/sdp/sdp_discovery.cc @@ -178,7 +178,7 @@ static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len, p_cmd->len = (uint16_t)(p - p_start); if (L2CA_DataWrite(p_ccb->connection_id, p_cmd) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, p_ccb->connection_id, p_cmd->len); } @@ -689,7 +689,7 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, p_msg->len = p - p_start; if (L2CA_DataWrite(p_ccb->connection_id, p_msg) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, p_ccb->connection_id, p_msg->len); } @@ -864,7 +864,7 @@ static void process_service_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply, p_msg->len = (uint16_t)(p - p_start); if (L2CA_DataWrite(p_ccb->connection_id, p_msg) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, p_ccb->connection_id, p_msg->len); } diff --git a/system/stack/sdp/sdp_server.cc b/system/stack/sdp/sdp_server.cc index 3902991645f..f7c68eec83f 100644 --- a/system/stack/sdp/sdp_server.cc +++ b/system/stack/sdp/sdp_server.cc @@ -304,7 +304,7 @@ static void process_service_search(tCONN_CB* p_ccb, uint16_t trans_num, /* Send the buffer through L2CAP */ if (L2CA_DataWrite(p_ccb->connection_id, p_buf) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, p_ccb->connection_id, p_buf->len); } @@ -703,7 +703,7 @@ static void process_service_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, /* Send the buffer through L2CAP */ if (L2CA_DataWrite(p_ccb->connection_id, p_buf) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, p_ccb->connection_id, p_buf->len); } @@ -1182,7 +1182,7 @@ static void process_service_search_attr_req(tCONN_CB* p_ccb, uint16_t trans_num, /* Send the buffer through L2CAP */ if (L2CA_DataWrite(p_ccb->connection_id, p_buf) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data peer:{} cid:{} len:{}", p_ccb->device_address, p_ccb->connection_id, p_buf->len); } diff --git a/system/stack/sdp/sdp_utils.cc b/system/stack/sdp/sdp_utils.cc index d22148f7f7c..4e5069130e9 100644 --- a/system/stack/sdp/sdp_utils.cc +++ b/system/stack/sdp/sdp_utils.cc @@ -740,7 +740,7 @@ void sdpu_build_n_send_error(tCONN_CB* p_ccb, uint16_t trans_num, /* Send the buffer through L2CAP */ if (L2CA_DataWrite(p_ccb->connection_id, p_buf) != - tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS) { + tL2CAP_DW_RESULT::SUCCESS) { log::warn("Unable to write L2CAP data cid:{}", p_ccb->connection_id); } } diff --git a/system/stack/smp/smp_utils.cc b/system/stack/smp/smp_utils.cc index eb586f32ff9..72892169daa 100644 --- a/system/stack/smp/smp_utils.cc +++ b/system/stack/smp/smp_utils.cc @@ -368,7 +368,7 @@ bool smp_send_msg_to_L2CAP(const RawAddress& rem_bda, BT_HDR* p_toL2CAP) { /* Unacked needs to be incremented before calling SendFixedChnlData */ smp_cb.total_tx_unacked++; l2cap_ret = L2CA_SendFixedChnlData(fixed_cid, rem_bda, p_toL2CAP); - if (l2cap_ret == tL2CAP_DW_RESULT::L2CAP_DW_FAILED) { + if (l2cap_ret == tL2CAP_DW_RESULT::FAILED) { smp_cb.total_tx_unacked--; log::error("SMP failed to pass msg to L2CAP"); return false; @@ -378,7 +378,7 @@ bool smp_send_msg_to_L2CAP(const RawAddress& rem_bda, BT_HDR* p_toL2CAP) { } l2cap_ret = L2CA_SendFixedChnlData(fixed_cid, rem_bda, p_toL2CAP); - if (l2cap_ret == tL2CAP_DW_RESULT::L2CAP_DW_FAILED) { + if (l2cap_ret == tL2CAP_DW_RESULT::FAILED) { log::error("SMP failed to pass msg to L2CAP"); return false; } else { diff --git a/system/stack/test/rfcomm/stack_rfcomm_test.cc b/system/stack/test/rfcomm/stack_rfcomm_test.cc index 0a54a2f5990..c30593a6d8b 100644 --- a/system/stack/test/rfcomm/stack_rfcomm_test.cc +++ b/system/stack/test/rfcomm/stack_rfcomm_test.cc @@ -179,7 +179,7 @@ class StackRfcommTest : public Test { BT_HDR* ua_channel_0 = AllocateWrappedOutgoingL2capAclPacket( CreateQuickUaPacket(RFCOMM_MX_DLCI, lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(ua_channel_0))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); // Packet should be freed by RFCOMM l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, sabm_channel_0); osi_free(ua_channel_0); @@ -200,7 +200,7 @@ class StackRfcommTest : public Test { lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_pn_rsp_to_peer))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); // uih_pn_cmd_from_peer should be freed by this method l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_pn_cmd_from_peer); osi_free(uih_pn_rsp_to_peer); @@ -228,7 +228,7 @@ class StackRfcommTest : public Test { BT_HDR* ua_channel_dlci = AllocateWrappedOutgoingL2capAclPacket( CreateQuickUaPacket(GetDlci(false, scn), lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(ua_channel_dlci))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); ASSERT_TRUE(security_callback); security_callback(peer_addr, BT_TRANSPORT_BR_EDR, p_port, BTM_SUCCESS); osi_free(ua_channel_dlci); @@ -244,13 +244,13 @@ class StackRfcommTest : public Test { // We also have to do modem configuration ourself EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_msc_response_to_peer))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); BT_HDR* uih_msc_cmd_to_peer = AllocateWrappedOutgoingL2capAclPacket( CreateQuickMscPacket(false, GetDlci(false, scn), lcid, acl_handle, true, false, true, true, false, true)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_msc_cmd_to_peer))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); // uih_msc_cmd_from_peer should be freed by this method l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_cmd_from_peer); osi_free(uih_msc_response_to_peer); @@ -281,7 +281,7 @@ class StackRfcommTest : public Test { } else { EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_pn_channel_3))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); } ASSERT_EQ(RFCOMM_CreateConnectionWithSecurity(uuid, scn, false, mtu, peer_bd_addr, client_handle, @@ -317,7 +317,7 @@ class StackRfcommTest : public Test { BT_HDR* sabm_channel_0 = AllocateWrappedOutgoingL2capAclPacket( CreateQuickSabmPacket(RFCOMM_MX_DLCI, lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(sabm_channel_0))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); l2cap_appl_info_.pL2CA_ConfigInd_Cb(lcid, &cfg_req); osi_free(sabm_channel_0); } @@ -340,7 +340,7 @@ class StackRfcommTest : public Test { RFCOMM_K_MAX, lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_pn_channel_3))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, ua_channel_0); osi_free(uih_pn_channel_3); } @@ -367,7 +367,7 @@ class StackRfcommTest : public Test { BT_HDR* sabm_channel_3 = AllocateWrappedOutgoingL2capAclPacket( CreateQuickSabmPacket(GetDlci(false, scn), lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(sabm_channel_3))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); ASSERT_TRUE(security_callback); security_callback(peer_addr, BT_TRANSPORT_BR_EDR, p_port, BTM_SUCCESS); osi_free(sabm_channel_3); @@ -382,7 +382,7 @@ class StackRfcommTest : public Test { CreateQuickMscPacket(true, GetDlci(false, scn), lcid, acl_handle, true, false, true, true, false, true)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_msc_cmd))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); BT_HDR* ua_channel_3 = AllocateWrappedIncomingL2capAclPacket( CreateQuickUaPacket(GetDlci(false, scn), lcid, acl_handle)); l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, ua_channel_3); @@ -405,7 +405,7 @@ class StackRfcommTest : public Test { false, true, true, false, true)); EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_msc_response_to_peer))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_cmd_from_peer); osi_free(uih_msc_response_to_peer); } @@ -421,7 +421,7 @@ class StackRfcommTest : public Test { credits, message)); uint16_t transmitted_length = 0; EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(data_packet))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); ASSERT_EQ(PORT_WriteData(port_handle, message.data(), message.size(), &transmitted_length), PORT_SUCCESS); @@ -795,7 +795,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { BT_HDR* ua_channel_0 = AllocateWrappedOutgoingL2capAclPacket( CreateQuickUaPacket(RFCOMM_MX_DLCI, new_lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(ua_channel_0))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); // And immediately try to configure test_peer_scn BT_HDR* uih_pn_cmd_to_peer = AllocateWrappedOutgoingL2capAclPacket( CreateQuickPnPacket(false, GetDlci(true, test_peer_scn), true, test_mtu, @@ -803,7 +803,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { new_lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(uih_pn_cmd_to_peer))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); // Packet should be freed by this method l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, sabm_channel_0); osi_free(ua_channel_0); @@ -823,7 +823,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(uih_pn_rsp_to_peer))) .Times(1) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, uih_pn_cmd_from_peer); osi_free(uih_pn_rsp_to_peer); @@ -851,7 +851,7 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { AllocateWrappedOutgoingL2capAclPacket(CreateQuickUaPacket( GetDlci(false, test_server_scn), new_lcid, acl_handle)); EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(ua_server_scn))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); // Callback should come from server port instead, client port will timeout // in 20 seconds EXPECT_CALL(rfcomm_callback_, @@ -870,13 +870,13 @@ TEST_F(StackRfcommTest, DISABLED_TestConnectionCollision) { // MPX_CTRL Modem Status Response (MSC) EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(uih_msc_rsp_to_peer))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); BT_HDR* uih_msc_cmd_to_peer = AllocateWrappedOutgoingL2capAclPacket( CreateQuickMscPacket(false, GetDlci(false, test_server_scn), new_lcid, acl_handle, true, false, true, true, false, true)); EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(uih_msc_cmd_to_peer))) - .WillOnce(Return(tL2CAP_DW_RESULT::L2CAP_DW_SUCCESS)); + .WillOnce(Return(tL2CAP_DW_RESULT::SUCCESS)); l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, uih_msc_cmd_from_peer); osi_free(uih_msc_rsp_to_peer); osi_free(uih_msc_cmd_to_peer); diff --git a/system/stack/test/sdp/stack_sdp_parse_test.cc b/system/stack/test/sdp/stack_sdp_parse_test.cc index 5822a596719..425c068c9eb 100644 --- a/system/stack/test/sdp/stack_sdp_parse_test.cc +++ b/system/stack/test/sdp/stack_sdp_parse_test.cc @@ -63,7 +63,7 @@ class StackSdpParserWithMocksTest : public ::testing::Test { test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t /* cid */, BT_HDR* p_data) { osi_free_and_reset((void**)&p_data); - return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::FAILED; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t /* cid */) { return true; }; diff --git a/system/stack/test/sdp/stack_sdp_test.cc b/system/stack/test/sdp/stack_sdp_test.cc index ffbf325b8ed..3dae98b571d 100644 --- a/system/stack/test/sdp/stack_sdp_test.cc +++ b/system/stack/test/sdp/stack_sdp_test.cc @@ -52,7 +52,7 @@ class StackSdpWithMocksTest : public ::testing::Test { test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t /* cid */, BT_HDR* p_data) -> tL2CAP_DW_RESULT { osi_free_and_reset((void**)&p_data); - return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::FAILED; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t /* cid */) { return true; }; diff --git a/system/stack/test/sdp/stack_sdp_utils_test.cc b/system/stack/test/sdp/stack_sdp_utils_test.cc index db1c224f968..b32227b7188 100644 --- a/system/stack/test/sdp/stack_sdp_utils_test.cc +++ b/system/stack/test/sdp/stack_sdp_utils_test.cc @@ -257,7 +257,7 @@ class StackSdpMockAndFakeTest : public ::testing::Test { test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t /* cid */, BT_HDR* p_data) -> tL2CAP_DW_RESULT { osi_free_and_reset((void**)&p_data); - return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::FAILED; }; test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t /* cid */) { return true; }; diff --git a/system/test/mock/mock_stack_l2cap_api.h b/system/test/mock/mock_stack_l2cap_api.h index c383e83c15b..2b0a13b68dc 100644 --- a/system/test/mock/mock_stack_l2cap_api.h +++ b/system/test/mock/mock_stack_l2cap_api.h @@ -379,7 +379,7 @@ struct L2CA_SendFixedChnlData { BT_HDR* p_buf)> body{[](uint16_t /* fixed_cid */, const RawAddress& /* rem_bda */, BT_HDR* /* p_buf */) -> tL2CAP_DW_RESULT { - return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::FAILED; }}; tL2CAP_DW_RESULT operator()(uint16_t fixed_cid, const RawAddress& rem_bda, BT_HDR* p_buf) { @@ -428,7 +428,7 @@ extern struct L2CA_MarkLeLinkAsActive L2CA_MarkLeLinkAsActive; struct L2CA_DataWrite { std::function body{ [](uint16_t /* cid */, BT_HDR* /* p_data */) -> tL2CAP_DW_RESULT { - return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::FAILED; }}; tL2CAP_DW_RESULT operator()(uint16_t cid, BT_HDR* p_data) { return body(cid, p_data); @@ -441,7 +441,7 @@ extern struct L2CA_DataWrite L2CA_DataWrite; struct L2CA_LECocDataWrite { std::function body{ [](uint16_t /* cid */, BT_HDR* /* p_data */) -> tL2CAP_DW_RESULT { - return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::FAILED; }}; tL2CAP_DW_RESULT operator()(uint16_t cid, BT_HDR* p_data) { return body(cid, p_data); diff --git a/system/test/mock/mock_stack_l2cap_main.cc b/system/test/mock/mock_stack_l2cap_main.cc index 98cb699ee55..5504d893257 100644 --- a/system/test/mock/mock_stack_l2cap_main.cc +++ b/system/test/mock/mock_stack_l2cap_main.cc @@ -27,7 +27,7 @@ tL2CAP_DW_RESULT l2c_data_write(uint16_t /* cid */, BT_HDR* /* p_data */, uint16_t /* flags */) { inc_func_call_count(__func__); - return tL2CAP_DW_RESULT::L2CAP_DW_FAILED; + return tL2CAP_DW_RESULT::FAILED; } void l2c_ccb_timer_timeout(void* /* data */) { inc_func_call_count(__func__); } void l2c_fcrb_ack_timer_timeout(void* /* data */) { -- GitLab From 2790960e0411284bd597503ec043b87c90f69bdc Mon Sep 17 00:00:00 2001 From: Gopi Sakshihally Bhuthaiah Date: Wed, 19 Jun 2024 06:31:22 +0000 Subject: [PATCH 0077/1446] Adding owners for Bluetooth Hid test Bug: 340549544 Test: atest -v HidHostTest Flag: EXEMPT Test ownership changes, no logical change Change-Id: I1a4e071444cec824f15f45916ca56cf4611d2772 --- framework/tests/bumble/src/android/bluetooth/hid/OWNERS | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 framework/tests/bumble/src/android/bluetooth/hid/OWNERS diff --git a/framework/tests/bumble/src/android/bluetooth/hid/OWNERS b/framework/tests/bumble/src/android/bluetooth/hid/OWNERS new file mode 100644 index 00000000000..75539edb096 --- /dev/null +++ b/framework/tests/bumble/src/android/bluetooth/hid/OWNERS @@ -0,0 +1,3 @@ +# Bug component: 27441 +# Project owners +rwt@google.com -- GitLab From 7276bfca4bc7dee6d6b708020f1ccf8354364f03 Mon Sep 17 00:00:00 2001 From: Onkar Shinde Date: Wed, 19 Jun 2024 13:15:26 +0530 Subject: [PATCH 0078/1446] Refactored avrcp_device_fuzz The following are updates to the fuzzer: 1. Added new APIs and randomized API calls. 2. Coverage improved from 44% to 75%. 3. Resolved assertion failure observed in b/333482486 Test: m avrcp_device_fuzz exec/s: 1900 Bug: 348101091 Change-Id: I6bf0af1c526a2228d6d6652af31c170d0394ee47 --- .../avrcp_device_fuzz/avrcp_device_fuzz.cc | 361 +++++++++++++++--- 1 file changed, 311 insertions(+), 50 deletions(-) diff --git a/system/profile/avrcp/tests/avrcp_device_fuzz/avrcp_device_fuzz.cc b/system/profile/avrcp/tests/avrcp_device_fuzz/avrcp_device_fuzz.cc index cf30d98cd92..32de7223266 100644 --- a/system/profile/avrcp/tests/avrcp_device_fuzz/avrcp_device_fuzz.cc +++ b/system/profile/avrcp/tests/avrcp_device_fuzz/avrcp_device_fuzz.cc @@ -1,77 +1,239 @@ -#include -#include +/* + * 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. + * + */ -#include "avrcp_packet.h" #include "device.h" +#include "fuzzer/FuzzedDataProvider.h" #include "internal_include/stack_config.h" #include "packet_test_helper.h" -#include "stack/include/a2dp_api.h" -#include "types/raw_address.h" +#include "pass_through_packet.h" bool btif_av_src_sink_coexist_enabled(void) { return true; } namespace bluetooth { namespace avrcp { + +static uint32_t kMinSize = 0; +static uint32_t kMaxSize = 10; +static uint32_t kMaxLen = 100; +static uint8_t kMinScope = 0; +static uint8_t kMaxScope = 3; +static uint8_t kMediaOpId = 0x44; +static uint8_t kMask = 0xFF; +static uint8_t k8BitShift = 8; + +const Opcode kValidOpCodes[] = {Opcode::VENDOR, Opcode::UNIT_INFO, + Opcode::SUBUNIT_INFO, Opcode::PASS_THROUGH}; + +const CType kValidCTypes[] = { + CType::CONTROL, CType::STATUS, CType::NOTIFY, + CType::NOT_IMPLEMENTED, CType::ACCEPTED, CType::REJECTED, + CType::STABLE, CType::CHANGED, CType::INTERIM}; + +const BrowsePdu kPduVal[] = {BrowsePdu::SET_BROWSED_PLAYER, + BrowsePdu::GET_FOLDER_ITEMS, + BrowsePdu::CHANGE_PATH, + BrowsePdu::GET_ITEM_ATTRIBUTES, + BrowsePdu::GET_TOTAL_NUMBER_OF_ITEMS, + BrowsePdu::GENERAL_REJECT}; + +const CommandPdu kCommandPduVal[] = { + CommandPdu::GET_CAPABILITIES, + CommandPdu::LIST_PLAYER_APPLICATION_SETTING_ATTRIBUTES, + CommandPdu::LIST_PLAYER_APPLICATION_SETTING_VALUES, + CommandPdu::GET_CURRENT_PLAYER_APPLICATION_SETTING_VALUE, + CommandPdu::SET_PLAYER_APPLICATION_SETTING_VALUE, + CommandPdu::GET_ELEMENT_ATTRIBUTES, + CommandPdu::GET_PLAY_STATUS, + CommandPdu::REGISTER_NOTIFICATION, + CommandPdu::SET_ABSOLUTE_VOLUME, + CommandPdu::SET_ADDRESSED_PLAYER, + CommandPdu::PLAY_ITEM}; + class FakeMediaInterface : public MediaInterface { public: - virtual void SendKeyEvent(uint8_t key, KeyState state) {} + FakeMediaInterface(FuzzedDataProvider* fdp) : mFdp(fdp) {} + void SendKeyEvent(uint8_t /* key */, KeyState /* state */) { return; } using SongInfoCallback = base::Callback; - virtual void GetSongInfo(SongInfoCallback info_cb) {} + void GetSongInfo(SongInfoCallback info_cb) { + SongInfo sInfo; + sInfo.media_id = mFdp->ConsumeRandomLengthString(kMaxLen); + sInfo.attributes.insert(AttributeEntry( + Attribute(mFdp->ConsumeIntegralInRange( + uint8_t(Attribute::TITLE), uint8_t(Attribute::DEFAULT_COVER_ART))), + mFdp->ConsumeRandomLengthString(kMaxLen))); + info_cb.Run(sInfo); + return; + } using PlayStatusCallback = base::Callback; - virtual void GetPlayStatus(PlayStatusCallback status_cb) {} + void GetPlayStatus(PlayStatusCallback status_cb) { + PlayStatus pst; + status_cb.Run(pst); + return; + } using NowPlayingCallback = base::Callback)>; - virtual void GetNowPlayingList(NowPlayingCallback now_playing_cb) {} + void GetNowPlayingList(NowPlayingCallback now_playing_cb) { + std::string currentSongId = mFdp->ConsumeRandomLengthString(kMaxLen); + size_t size = mFdp->ConsumeIntegralInRange(kMinSize, kMaxSize); + std::vector songInfoVec; + for (size_t iter = 0; iter < size; ++iter) { + SongInfo tempSongInfo; + tempSongInfo.media_id = mFdp->ConsumeRandomLengthString(kMaxLen); + tempSongInfo.attributes.insert( + AttributeEntry(Attribute(mFdp->ConsumeIntegralInRange( + uint8_t(Attribute::TITLE), + uint8_t(Attribute::DEFAULT_COVER_ART))), + mFdp->ConsumeRandomLengthString(kMaxLen))); + songInfoVec.push_back(tempSongInfo); + } + now_playing_cb.Run(currentSongId, songInfoVec); + return; + } using MediaListCallback = base::Callback)>; - virtual void GetMediaPlayerList(MediaListCallback list_cb) {} + void GetMediaPlayerList(MediaListCallback list_cb) { + uint16_t currentPlayer = mFdp->ConsumeIntegral(); + size_t size = mFdp->ConsumeIntegralInRange(kMinSize, kMaxSize); + std::vector playerList; + for (size_t iter = 0; iter < size; ++iter) { + MediaPlayerInfo tempInfo; + tempInfo.id = mFdp->ConsumeIntegral(); + tempInfo.name = mFdp->ConsumeRandomLengthString(kMaxLen); + tempInfo.browsing_supported = mFdp->ConsumeBool(); + playerList.push_back(tempInfo); + } + list_cb.Run(currentPlayer, playerList); + return; + } using FolderItemsCallback = base::Callback)>; - virtual void GetFolderItems(uint16_t player_id, std::string media_id, - FolderItemsCallback folder_cb) {} + void GetFolderItems(uint16_t /* player_id */, std::string /* media_id */, + FolderItemsCallback folder_cb) { + size_t size = mFdp->ConsumeIntegralInRange(kMinSize, kMaxSize); + std::vector list; + for (size_t iter = 0; iter < size; ++iter) { + ListItem tempList; + tempList.type = mFdp->ConsumeBool() ? ListItem::FOLDER : ListItem::SONG; + tempList.folder.media_id = mFdp->ConsumeRandomLengthString(kMaxLen); + tempList.folder.name = mFdp->ConsumeRandomLengthString(kMaxLen); + tempList.folder.is_playable = mFdp->ConsumeBool(); + tempList.song.media_id = mFdp->ConsumeRandomLengthString(kMaxLen); + tempList.song.attributes.insert( + AttributeEntry(Attribute(mFdp->ConsumeIntegralInRange( + uint8_t(Attribute::TITLE), + uint8_t(Attribute::DEFAULT_COVER_ART))), + mFdp->ConsumeRandomLengthString(kMaxLen))); + list.push_back(tempList); + } + folder_cb.Run(list); + } using SetBrowsedPlayerCallback = base::Callback; - virtual void SetBrowsedPlayer(uint16_t player_id, - SetBrowsedPlayerCallback browse_cb) {} - virtual void PlayItem(uint16_t player_id, bool now_playing, - std::string media_id) {} - virtual void SetActiveDevice(const RawAddress& address) {} - virtual void RegisterUpdateCallback(MediaCallbacks* callback) {} - virtual void UnregisterUpdateCallback(MediaCallbacks* callback) {} + void SetBrowsedPlayer(uint16_t player_id, + SetBrowsedPlayerCallback browse_cb) { + std::string rootId = mFdp->ConsumeRandomLengthString(kMaxLen); + uint32_t numItems = mFdp->ConsumeIntegral(); + browse_cb.Run(player_id, rootId, numItems); + return; + } + void PlayItem(uint16_t /* player_id */, bool /* now_playing */, + std::string /* media_id */) { + return; + } + void SetActiveDevice(const RawAddress& /* address */) { return; } + void RegisterUpdateCallback(MediaCallbacks* /* callback */) { return; } + void UnregisterUpdateCallback(MediaCallbacks* /* callback */) { return; } + + private: + FuzzedDataProvider* mFdp; }; class FakeVolumeInterface : public VolumeInterface { public: - virtual void DeviceConnected(const RawAddress& bdaddr) {} - virtual void DeviceConnected(const RawAddress& bdaddr, VolumeChangedCb cb) {} - virtual void DeviceDisconnected(const RawAddress& bdaddr) {} - virtual void SetVolume(int8_t volume) {} + FakeVolumeInterface(FuzzedDataProvider* fdp) : mFdp(fdp) {} + void DeviceConnected(const RawAddress& /* bdaddr */) { return; } + void DeviceConnected(const RawAddress& /* bdaddr */, VolumeChangedCb cb) { + uint8_t volume = mFdp->ConsumeIntegral(); + cb.Run(volume); + return; + } + void DeviceDisconnected(const RawAddress& /* bdaddr */) { return; } + void SetVolume(int8_t /* volume */) { return; } + + private: + FuzzedDataProvider* mFdp; }; class FakePlayerSettingsInterface : public PlayerSettingsInterface { public: - virtual void ListPlayerSettings(ListPlayerSettingsCallback cb) {} - virtual void ListPlayerSettingValues(PlayerAttribute setting, - ListPlayerSettingValuesCallback cb) {} - virtual void GetCurrentPlayerSettingValue( - std::vector attributes, - GetCurrentPlayerSettingValueCallback cb) {} - virtual void SetPlayerSettings(std::vector attributes, - std::vector values, - SetPlayerSettingValueCallback cb) {} + FakePlayerSettingsInterface(FuzzedDataProvider* fdp) : mFdp(fdp) {} + void ListPlayerSettings(ListPlayerSettingsCallback cb) { + uint8_t label = mFdp->ConsumeIntegral(); + size_t size = mFdp->ConsumeIntegralInRange(kMinSize, kMaxSize); + std::vector attributes; + for (size_t iter = 0; iter < size; ++iter) { + PlayerAttribute playerAttr = + (PlayerAttribute)mFdp->ConsumeIntegralInRange( + uint8_t(PlayerAttribute::EQUALIZER), + uint8_t(PlayerAttribute::SCAN)); + attributes.push_back(playerAttr); + } + cb.Run(attributes); + return; + } + void ListPlayerSettingValues(PlayerAttribute setting, + ListPlayerSettingValuesCallback cb) { + size_t size = mFdp->ConsumeIntegralInRange(kMinSize, kMaxSize); + std::vector values = mFdp->ConsumeBytes(size); + cb.Run(setting, values); + return; + } + void GetCurrentPlayerSettingValue(std::vector attributes, + GetCurrentPlayerSettingValueCallback cb) { + std::vector values(attributes.size()); + for (size_t iter = 0; iter < attributes.size(); ++iter) { + values.push_back(mFdp->ConsumeIntegral()); + } + cb.Run(attributes, values); + return; + } + void SetPlayerSettings(std::vector /* attributes */, + std::vector /* values */, + SetPlayerSettingValueCallback cb) { + bool success = mFdp->ConsumeBool(); + cb.Run(success); + return; + } + + private: + FuzzedDataProvider* mFdp; }; class FakeA2dpInterface : public A2dpInterface { public: - virtual RawAddress active_peer() { return RawAddress(); } - virtual bool is_peer_in_silence_mode(const RawAddress& peer_address) { + RawAddress active_peer() { return RawAddress::kAny; } + bool is_peer_in_silence_mode(const RawAddress& /* peer_address */) { return false; } - virtual void connect_audio_sink_delayed(uint8_t handle, - const RawAddress& peer_address) { + void connect_audio_sink_delayed(uint8_t /* handle */, + const RawAddress& /* peer_address */) { return; } - virtual uint16_t find_audio_sink_service(const RawAddress& peer_address, - tA2DP_FIND_CBACK p_cback) override { + uint16_t find_audio_sink_service(const RawAddress& /* peer_address */, + tA2DP_FIND_CBACK /* p_cback */) override { return 0; } }; @@ -103,25 +265,124 @@ const stack_config_t interface = {get_pts_avrcp_test, void Callback(uint8_t, bool, std::unique_ptr<::bluetooth::PacketBuilder>) {} -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { - FakeMediaInterface fmi; - FakeVolumeInterface fvi; +class AVRCPDeviceFuzzer { + public: + AVRCPDeviceFuzzer(const uint8_t* Data, size_t Size) : mFdp(Data, Size) {} + void Process(); + + private: + void CreateBrowsePacket(std::vector& packet); + void CreateAvrcpPacket(std::vector& packet); + FuzzedDataProvider mFdp; +}; + +void AVRCPDeviceFuzzer::CreateBrowsePacket(std::vector& packet) { + // Used to consume a maximum of 50% of the data to create packet. + // This ensures that we don't completely exhaust data and use the rest 50% for + // fuzzing of APIs. + packet = mFdp.ConsumeBytes(mFdp.ConsumeIntegralInRange( + 0, mFdp.remaining_bytes() * 50 / 100)); + + if (packet.size() < Packet::kMinSize()) { + packet.resize(Packet::kMinSize()); + } + packet[0] = (uint8_t)mFdp.PickValueInArray(kPduVal); + // Set packet[1] and packet[2] to corresponding value of little endian + uint16_t size = packet.size() - BrowsePacket::kMinSize(); + packet[1] = (size >> k8BitShift) & kMask; + packet[2] = size & kMask; +} + +void AVRCPDeviceFuzzer::CreateAvrcpPacket(std::vector& packet) { + // Used to consume a maximum of 50% of the data to create packet. + // This ensures that we don't completely exhaust data and use the rest 50% for + // fuzzing of APIs. + packet = mFdp.ConsumeBytes(mFdp.ConsumeIntegralInRange( + 0, mFdp.remaining_bytes() * 50 / 100)); + if (packet.size() < Packet::kMinSize()) { + packet.resize(Packet::kMinSize()); + } + packet[0] = (uint8_t)mFdp.PickValueInArray(kValidCTypes); + packet[2] = (uint8_t)mFdp.PickValueInArray(kValidOpCodes); + if (packet[2] == uint8_t(Opcode::PASS_THROUGH)) { + packet.resize(PassThroughPacket::kMinSize()); + packet[3] = + mFdp.ConsumeBool() ? kMediaOpId : mFdp.ConsumeIntegral(); + } else if (packet[2] == uint8_t(Opcode::VENDOR)) { + if (packet.size() <= VendorPacket::kMinSize()) { + packet.resize(VendorPacket::kMinSize() + 1); + } + packet[3] = mFdp.ConsumeIntegralInRange(kMinScope, kMaxScope); + packet[5] = (uint8_t)mFdp.ConsumeBool(); // Direction + packet[6] = (uint8_t)mFdp.PickValueInArray(kCommandPduVal); + // Set packet[8] and packet[9] to corresponding value of little endian + uint16_t size = packet.size() - VendorPacket::kMinSize(); + packet[8] = (size >> k8BitShift) & kMask; + packet[9] = size & kMask; + } +} +void AVRCPDeviceFuzzer::Process() { + FakeMediaInterface fmi(&mFdp); + FakeVolumeInterface fvi(&mFdp); FakeA2dpInterface fai; - FakePlayerSettingsInterface fpsi; + FakePlayerSettingsInterface fpsi(&mFdp); - std::vector Packet(Data, Data + Size); Device device( - RawAddress::kAny, true, + RawAddress::kAny /* bdaddr */, + mFdp.ConsumeBool() /* avrcp13_compatibility */, base::BindRepeating( - [](uint8_t, bool, std::unique_ptr<::bluetooth::PacketBuilder>) {}), - 0xFFFF, 0xFFFF); + [](uint8_t, bool, std::unique_ptr<::bluetooth::PacketBuilder>) { + }) /* send_msg_cb */, + mFdp.ConsumeIntegral() /* ctrl_mtu */, + mFdp.ConsumeIntegral() /* browse_mtu */); + device.RegisterInterfaces(&fmi, &fai, &fvi, &fpsi); - auto browse_request = TestPacketType::Make(Packet); - device.BrowseMessageReceived(1, browse_request); + while (mFdp.remaining_bytes()) { + auto invokeAVRCP = mFdp.PickValueInArray>({ + [&]() { + device.SetBrowseMtu( + mFdp.ConsumeIntegral() /* browse_mtu */); + }, + [&]() { + device.SetBipClientStatus(mFdp.ConsumeBool() /* connected */); + }, + [&]() { + std::vector browse_packet; + CreateBrowsePacket(browse_packet); + auto browse_request = + TestPacketType::Make(browse_packet); + device.BrowseMessageReceived( + mFdp.ConsumeIntegral() /* label */, browse_request); + }, + [&]() { + /* Crafting PassThroughPacket Packets */ + std::vector avrcp_packet; + CreateAvrcpPacket(avrcp_packet); + auto avrcp_request = + TestPacketType::Make(avrcp_packet); + device.MessageReceived(mFdp.ConsumeIntegral() /* label */, + avrcp_request); + }, + [&]() { + device.SendMediaUpdate(mFdp.ConsumeBool() /* metadata */, + mFdp.ConsumeBool() /* play_status */, + mFdp.ConsumeBool() /* queue */); + }, + [&]() { + device.SendFolderUpdate(mFdp.ConsumeBool() /* available_players */, + mFdp.ConsumeBool() /* addressed_player */, + mFdp.ConsumeBool() /* uids */); + }, + }); + invokeAVRCP(); + } + device.DeviceDisconnected(); +} - auto avrcp_request = TestPacketType::Make(Packet); - device.MessageReceived(1, avrcp_request); +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { + AVRCPDeviceFuzzer avrcp_device_fuzzer(Data, Size); + avrcp_device_fuzzer.Process(); return 0; } } // namespace avrcp -- GitLab From 5deece0f399eaa040d3fdb39fecb35e92800a9cc Mon Sep 17 00:00:00 2001 From: Jim Tang Date: Wed, 19 Jun 2024 17:11:42 +0800 Subject: [PATCH 0079/1446] Cleanup Bluetooth build files This commit cleans up: - find command does not support bracket {} in a genrule command, resulting build noise. Use a for loop to mitigate the message. - LOCAL_host_python_libraries is a remaining variable and not defined at all. Bug: 338000376 Test: m bluetooth_stack_with_facade Change-Id: Iee665089281d93d02ea0b67e2f2acdae438e2ecf --- system/Android.bp | 2 +- system/Android.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/Android.bp b/system/Android.bp index 87de62ae758..8a39be0608c 100644 --- a/system/Android.bp +++ b/system/Android.bp @@ -133,7 +133,7 @@ genrule { ], cmd: "mkdir -p $(genDir)/files && " + "$(location aprotoc) -Ipackages/modules/Bluetooth/system -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-python-plugin) $(locations :BlueberryFacadeProto) --grpc_out=$(genDir)/files --python_out=$(genDir)/files && " + - "find $(genDir)/files -type d -exec touch {}/__init__.py \\; &&" + + "for dir in `find $(genDir)/files -type d`; do touch $$dir/__init__.py; done &&" + "$(location soong_zip) -C $(genDir)/files -D $(genDir)/files -o $(out)", srcs: [ ":BlueberryFacadeProto", diff --git a/system/Android.mk b/system/Android.mk index 91ff549b89e..fbda34b1891 100644 --- a/system/Android.mk +++ b/system/Android.mk @@ -98,7 +98,7 @@ $(bluetooth_cert_src_and_bin_zip): PRIVATE_host_python_smp_packets_library := $( $(bluetooth_cert_src_and_bin_zip): PRIVATE_target_executables := $(LOCAL_target_executables) $(bluetooth_cert_src_and_bin_zip): PRIVATE_target_libraries := $(LOCAL_target_libraries) $(bluetooth_cert_src_and_bin_zip): $(SOONG_ZIP) $(LOCAL_cert_test_sources) \ - $(LOCAL_host_executables) $(LOCAL_host_libraries) $(LOCAL_host_python_libraries) \ + $(LOCAL_host_executables) $(LOCAL_host_libraries) \ $(LOCAL_host_python_hci_packets_library) \ $(LOCAL_host_python_smp_packets_library) \ $(LOCAL_target_executables) $(LOCAL_target_libraries) -- GitLab From 4bc0bd81fb9493b1e43d0b788d8275c07ec89eae Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Fri, 14 Jun 2024 11:05:09 -0700 Subject: [PATCH 0080/1446] stack::sec::btm_sec_rmt_name_request_complete Log peer device When rnr completes without a security record log the peer address too. Bug: 347289482 Test: m . Flag: EXEMPT, Logging Change Change-Id: I601fbc2da5645095a722081d65a328671ecd1ca4 --- system/stack/btm/btm_sec.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/system/stack/btm/btm_sec.cc b/system/stack/btm/btm_sec.cc index f799aaecf84..8faba17825c 100644 --- a/system/stack/btm/btm_sec.cc +++ b/system/stack/btm/btm_sec.cc @@ -2316,8 +2316,10 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, if (p_dev_rec == nullptr) { log::debug( - "Remote read request complete for unknown device pairing_state:{} " + "Remote read request complete for unknown device peer:{} " + "pairing_state:{} " "status:{} name:{}", + (p_bd_addr) ? ADDRESS_TO_LOGGABLE_CSTR(*p_bd_addr) : "null", tBTM_SEC_CB::btm_pair_state_descr(btm_sec_cb.pairing_state), hci_status_code_text(status), reinterpret_cast(p_bd_name)); -- GitLab From 2cf0a29d6504f29c17488e50e2f963bb969fc709 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Wed, 19 Jun 2024 20:55:48 +0200 Subject: [PATCH 0081/1446] Add flag l2cap_update_existing_conn_interval_with_base_interval Bug: 348209161 Bug: 315241296 Test: m -j; Change-Id: I925b581ca4a8a9e46010ff1ec5933b4631235523 --- flags/l2cap.aconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/flags/l2cap.aconfig b/flags/l2cap.aconfig index 2cc815b785d..9327e019da2 100644 --- a/flags/l2cap.aconfig +++ b/flags/l2cap.aconfig @@ -24,3 +24,13 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "l2cap_update_existing_conn_interval_with_base_interval" + namespace: "bluetooth" + description: "Update existing connection intervals when base ecosystem interval is set" + bug: "348209161" + metadata { + purpose: PURPOSE_BUGFIX + } +} -- GitLab From a27448a81c3aee5927270983011a950c43fbfff3 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Fri, 14 Jun 2024 16:04:12 -0700 Subject: [PATCH 0082/1446] stack::sec Move old_sec_state to where it is changed Bug: 347349670 Test: m . Flag: EXEMPT, Mechanical Refactor Change-Id: I652e1701392a561efbcb1716c802052254effe1a --- system/stack/btm/btm_sec.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/stack/btm/btm_sec.cc b/system/stack/btm/btm_sec.cc index 8faba17825c..460f9d4dbd8 100644 --- a/system/stack/btm/btm_sec.cc +++ b/system/stack/btm/btm_sec.cc @@ -2328,7 +2328,6 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, return; } - uint8_t old_sec_state = p_dev_rec->sec_rec.sec_state; if (status == HCI_SUCCESS) { log::debug( "Remote read request complete for known device pairing_state:{} " @@ -2354,6 +2353,7 @@ void btm_sec_rmt_name_request_complete(const RawAddress* p_bd_addr, p_dev_rec->sec_bd_name[0] = 0; } + uint8_t old_sec_state = p_dev_rec->sec_rec.sec_state; if (p_dev_rec->sec_rec.sec_state == BTM_SEC_STATE_GETTING_NAME) p_dev_rec->sec_rec.sec_state = BTM_SEC_STATE_IDLE; -- GitLab From d8fb1d1446f945904a9a1b416fa64a1e54d4f017 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Sat, 25 May 2024 09:41:50 -0700 Subject: [PATCH 0083/1446] [8/19] get_btm_client_interface().peer.BTM_GetMaxPacketSize Bug: 343772702 Test: m . Flag: EXEMPT, Mechanical Refactor Change-Id: I24b797f0a2936e7932065646271b02c630dcd8dd --- system/stack/l2cap/l2c_utils.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/system/stack/l2cap/l2c_utils.cc b/system/stack/l2cap/l2c_utils.cc index 7be06b473b1..46a6181da00 100644 --- a/system/stack/l2cap/l2c_utils.cc +++ b/system/stack/l2cap/l2c_utils.cc @@ -37,6 +37,7 @@ #include "stack/include/bt_hdr.h" #include "stack/include/bt_types.h" #include "stack/include/btm_api.h" +#include "stack/include/btm_client_interface.h" #include "stack/include/hci_error_code.h" #include "stack/include/hcidefs.h" #include "stack/include/l2c_api.h" @@ -2615,7 +2616,8 @@ void l2cu_adjust_out_mps(tL2C_CCB* p_ccb) { uint16_t packet_size; /* on the tx side MTU is selected based on packet size of the controller */ - packet_size = BTM_GetMaxPacketSize(p_ccb->p_lcb->remote_bd_addr); + packet_size = get_btm_client_interface().peer.BTM_GetMaxPacketSize( + p_ccb->p_lcb->remote_bd_addr); if (packet_size <= (L2CAP_PKT_OVERHEAD + L2CAP_FCR_OVERHEAD + L2CAP_SDU_LEN_OVERHEAD + L2CAP_FCS_LEN)) { -- GitLab From ed26173a41649e4a6004805ecde831a006389007 Mon Sep 17 00:00:00 2001 From: William Escande Date: Wed, 19 Jun 2024 18:16:11 -0700 Subject: [PATCH 0084/1446] InCallService: Refresh test and use injection Bug: 330247213 Fix: 330247213 Test: atest BluetoothInstrumentationTests:BluetoothInCallServiceTest Flag: TEST_ONLY Change-Id: I323975fc8ab438ded04f86d72059079996000c24 --- .../telephony/BluetoothInCallService.java | 24 +- .../telephony/BluetoothInCallServiceTest.java | 1002 +++++++---------- 2 files changed, 437 insertions(+), 589 deletions(-) diff --git a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java index 7f372008b16..dbeee8cf818 100644 --- a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java +++ b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java @@ -137,7 +137,7 @@ public class BluetoothInCallService extends InCallService { private static BluetoothInCallService sInstance = null; - public CallInfo mCallInfo = new CallInfo(); + private final CallInfo mCallInfo; protected boolean mOnCreateCalled = false; @@ -346,12 +346,31 @@ public class BluetoothInCallService extends InCallService { return super.onUnbind(intent); } - public BluetoothInCallService() { + private BluetoothInCallService(CallInfo callInfo) { Log.i(TAG, "BluetoothInCallService is created"); + mCallInfo = Objects.requireNonNullElse(callInfo, new CallInfo()); sInstance = this; mExecutor = Executors.newSingleThreadExecutor(); } + public BluetoothInCallService() { + this(null); + } + + @VisibleForTesting + BluetoothInCallService( + Context context, + CallInfo callInfo, + BluetoothHeadsetProxy headset, + BluetoothLeCallControlProxy leCallControl) { + this(callInfo); + mBluetoothHeadset = headset; + mBluetoothLeCallControl = leCallControl; + attachBaseContext(context); + mTelephonyManager = getSystemService(TelephonyManager.class); + mTelecomManager = getSystemService(TelecomManager.class); + } + public static BluetoothInCallService getInstance() { return sInstance; } @@ -1551,7 +1570,6 @@ public class BluetoothInCallService extends InCallService { return null; } } - ; @VisibleForTesting public void setBluetoothLeCallControl(BluetoothLeCallControlProxy bluetoothTbs) { diff --git a/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java index 2007a2c5458..4d639e79bfd 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java @@ -23,14 +23,11 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothLeCallControl; import android.content.ComponentName; import android.content.Context; +import android.content.ContextWrapper; import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ApplicationInfo; import android.net.Uri; import android.os.Binder; -import android.os.Build; import android.os.Bundle; -import android.os.IBinder; import android.telecom.BluetoothCallQualityReport; import android.telecom.Call; import android.telecom.Connection; @@ -38,21 +35,18 @@ import android.telecom.DisconnectCause; import android.telecom.GatewayInfo; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; -import android.telecom.TelecomManager; import android.telephony.PhoneNumberUtils; import android.telephony.TelephonyManager; import android.util.Log; import androidx.test.core.app.ApplicationProvider; 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; import com.android.bluetooth.hfp.BluetoothHeadsetProxy; import com.android.bluetooth.tbs.BluetoothLeCallControlProxy; -import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -67,7 +61,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; -import java.util.concurrent.TimeUnit; /** Tests for {@link BluetoothInCallService} */ @MediumTest @@ -96,79 +89,34 @@ public class BluetoothInCallServiceTest { // Add all held calls to a conference private static final int CHLD_TYPE_ADDHELDTOCONF = 3; - private TestableBluetoothInCallService mBluetoothInCallService; - - @Rule - public final ServiceTestRule mServiceRule = ServiceTestRule.withTimeout(1, TimeUnit.SECONDS); + private BluetoothInCallService mBluetoothInCallService; @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @Mock private BluetoothHeadsetProxy mMockBluetoothHeadset; - @Mock private BluetoothLeCallControlProxy mMockBluetoothLeCallControl; + @Mock private BluetoothLeCallControlProxy mLeCallControl; @Mock private BluetoothInCallService.CallInfo mMockCallInfo; - @Mock private TelephonyManager mMockTelephonyManager; - @Mock private Context mContext; - - private static class TestableBluetoothInCallService extends BluetoothInCallService { - @Override - public IBinder onBind(Intent intent) { - IBinder binder = super.onBind(intent); - IntentFilter intentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); - intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); - registerReceiver(mBluetoothAdapterReceiver, intentFilter); - mTelephonyManager = getSystemService(TelephonyManager.class); - mTelecomManager = getSystemService(TelecomManager.class); - return binder; - } - - @Override - protected void enforceModifyPermission() {} - protected void setOnCreateCalled(boolean called) { - mOnCreateCalled = called; - } - } + private TelephonyManager mMockTelephonyManager; @Before - public void setUp() throws Exception { - InstrumentationRegistry.getInstrumentation() - .getUiAutomation() - .adoptShellPermissionIdentity(); - - // Create the service Intent. - Intent serviceIntent = - new Intent( - ApplicationProvider.getApplicationContext(), - TestableBluetoothInCallService.class); - // Bind the service - mServiceRule.bindService(serviceIntent); - - // Ensure initialization does not actually try to access any of the CallsManager fields. - // This also works to return null if it is not overwritten later in the test. - doReturn(null).when(mMockCallInfo).getActiveCall(); - doReturn(null).when(mMockCallInfo).getRingingOrSimulatedRingingCall(); - doReturn(null).when(mMockCallInfo).getHeldCall(); - doReturn(null).when(mMockCallInfo).getOutgoingCall(); - doReturn(0).when(mMockCallInfo).getNumHeldCalls(); - doReturn(false).when(mMockCallInfo).hasOnlyDisconnectedCalls(); + public void setUp() { doReturn(true).when(mMockCallInfo).isNullCall(null); doReturn(false).when(mMockCallInfo).isNullCall(notNull()); - mBluetoothInCallService = new TestableBluetoothInCallService(); - mBluetoothInCallService.setBluetoothHeadset(mMockBluetoothHeadset); - mBluetoothInCallService.setBluetoothLeCallControl(mMockBluetoothLeCallControl); - mBluetoothInCallService.mCallInfo = mMockCallInfo; - mBluetoothInCallService.setOnCreateCalled(true); - } + Context spiedContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); + mMockTelephonyManager = + TestUtils.mockGetSystemService( + spiedContext, Context.TELEPHONY_SERVICE, TelephonyManager.class); - @After - public void tearDown() throws Exception { - mServiceRule.unbindService(); - mBluetoothInCallService = null; + mBluetoothInCallService = + new BluetoothInCallService( + spiedContext, mMockCallInfo, mMockBluetoothHeadset, mLeCallControl); + mBluetoothInCallService.onCreate(); } @Test - public void testHeadsetAnswerCall() throws Exception { + public void headsetAnswerCall() { BluetoothCall mockCall = createRingingCall(UUID.randomUUID()); boolean callAnswered = mBluetoothInCallService.answerCall(); @@ -178,15 +126,13 @@ public class BluetoothInCallServiceTest { } @Test - public void testHeadsetAnswerCallNull() throws Exception { - when(mMockCallInfo.getRingingOrSimulatedRingingCall()).thenReturn(null); - + public void headsetAnswerCallNull() { boolean callAnswered = mBluetoothInCallService.answerCall(); Assert.assertFalse(callAnswered); } @Test - public void testHeadsetHangupCall() throws Exception { + public void headsetHangupCall() { BluetoothCall mockCall = createForegroundCall(UUID.randomUUID()); boolean callHungup = mBluetoothInCallService.hangupCall(); @@ -196,15 +142,13 @@ public class BluetoothInCallServiceTest { } @Test - public void testHeadsetHangupCallNull() throws Exception { - when(mMockCallInfo.getForegroundCall()).thenReturn(null); - + public void headsetHangupCallNull() { boolean callHungup = mBluetoothInCallService.hangupCall(); Assert.assertFalse(callHungup); } @Test - public void testHeadsetSendDTMF() throws Exception { + public void headsetSendDTMF() { BluetoothCall mockCall = createForegroundCall(UUID.randomUUID()); boolean sentDtmf = mBluetoothInCallService.sendDtmf(TEST_DTMF_TONE); @@ -215,62 +159,55 @@ public class BluetoothInCallServiceTest { } @Test - public void testHeadsetSendDTMFNull() throws Exception { - when(mMockCallInfo.getForegroundCall()).thenReturn(null); - + public void headsetSendDTMFNull() { boolean sentDtmf = mBluetoothInCallService.sendDtmf(TEST_DTMF_TONE); Assert.assertFalse(sentDtmf); } @Test - public void testGetNetworkOperator() throws Exception { + public void getNetworkOperator() { PhoneAccount fakePhoneAccount = makeQuickAccount("id0", TEST_ACCOUNT_INDEX); - when(mMockCallInfo.getBestPhoneAccount()).thenReturn(fakePhoneAccount); + doReturn(fakePhoneAccount).when(mMockCallInfo).getBestPhoneAccount(); String networkOperator = mBluetoothInCallService.getNetworkOperator(); Assert.assertEquals(networkOperator, "label0"); } @Test - public void testGetNetworkOperatorNoPhoneAccount() throws Exception { - when(mMockCallInfo.getForegroundCall()).thenReturn(null); - when(mMockTelephonyManager.getNetworkOperatorName()).thenReturn("label1"); - mBluetoothInCallService.mTelephonyManager = mMockTelephonyManager; + public void getNetworkOperatorNoPhoneAccount() { + final String fakeOperator = "label1"; + doReturn(fakeOperator).when(mMockTelephonyManager).getNetworkOperatorName(); String networkOperator = mBluetoothInCallService.getNetworkOperator(); - Assert.assertEquals(networkOperator, "label1"); + Assert.assertEquals(networkOperator, fakeOperator); } @Test - public void testGetSubscriberNumber() throws Exception { + public void getSubscriberNumber() { PhoneAccount fakePhoneAccount = makeQuickAccount("id0", TEST_ACCOUNT_INDEX); - when(mMockCallInfo.getBestPhoneAccount()).thenReturn(fakePhoneAccount); + doReturn(fakePhoneAccount).when(mMockCallInfo).getBestPhoneAccount(); String subscriberNumber = mBluetoothInCallService.getSubscriberNumber(); Assert.assertEquals(subscriberNumber, TEST_ACCOUNT_ADDRESS + TEST_ACCOUNT_INDEX); } @Test - public void testGetSubscriberNumberFallbackToTelephony() throws Exception { - String fakeNumber = "8675309"; - when(mMockCallInfo.getBestPhoneAccount()).thenReturn(null); - when(mMockTelephonyManager.getLine1Number()).thenReturn(fakeNumber); - mBluetoothInCallService.mTelephonyManager = mMockTelephonyManager; + public void getSubscriberNumberFallbackToTelephony() { + final String fakeNumber = "8675309"; + doReturn(fakeNumber).when(mMockTelephonyManager).getLine1Number(); String subscriberNumber = mBluetoothInCallService.getSubscriberNumber(); Assert.assertEquals(subscriberNumber, fakeNumber); } @Test - public void testListCurrentCallsOneCall() throws Exception { - ArrayList calls = new ArrayList<>(); + public void listCurrentCallsOneCall() { BluetoothCall activeCall = createActiveCall(UUID.randomUUID()); - when(activeCall.getState()).thenReturn(Call.STATE_ACTIVE); - calls.add(activeCall); + doReturn(Call.STATE_ACTIVE).when(activeCall).getState(); + doReturn(Uri.parse("tel:555-000")).when(activeCall).getHandle(); + + doReturn(List.of(activeCall)).when(mMockCallInfo).getBluetoothCalls(); mBluetoothInCallService.onCallAdded(activeCall); - when(activeCall.isConference()).thenReturn(false); - when(activeCall.getHandle()).thenReturn(Uri.parse("tel:555-000")); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); @@ -292,9 +229,8 @@ public class BluetoothInCallServiceTest { * Telecom. */ @Test - public void testBluetoothCallQualityReport() { + public void bluetoothCallQualityReport() { BluetoothCall activeCall = createForegroundCall(UUID.randomUUID()); - when(activeCall.isCallNull()).thenReturn(false); mBluetoothInCallService.onCallAdded(activeCall); mBluetoothInCallService.sendBluetoothCallQualityReport( @@ -324,18 +260,15 @@ public class BluetoothInCallServiceTest { } @Test - public void testListCurrentCallsSilentRinging() throws Exception { - ArrayList calls = new ArrayList<>(); + public void listCurrentCallsSilentRinging() { BluetoothCall silentRingingCall = createActiveCall(UUID.randomUUID()); - when(silentRingingCall.getState()).thenReturn(Call.STATE_RINGING); - when(silentRingingCall.isSilentRingingRequested()).thenReturn(true); - calls.add(silentRingingCall); - mBluetoothInCallService.onCallAdded(silentRingingCall); + doReturn(Call.STATE_RINGING).when(silentRingingCall).getState(); + doReturn(true).when(silentRingingCall).isSilentRingingRequested(); + doReturn(Uri.parse("tel:555-000")).when(silentRingingCall).getHandle(); - when(silentRingingCall.isConference()).thenReturn(false); - when(silentRingingCall.getHandle()).thenReturn(Uri.parse("tel:555-000")); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); - when(mMockCallInfo.getRingingOrSimulatedRingingCall()).thenReturn(silentRingingCall); + doReturn(List.of(silentRingingCall)).when(mMockCallInfo).getBluetoothCalls(); + doReturn(silentRingingCall).when(mMockCallInfo).getRingingOrSimulatedRingingCall(); + mBluetoothInCallService.onCallAdded(silentRingingCall); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); @@ -353,43 +286,39 @@ public class BluetoothInCallServiceTest { } @Test - public void testConferenceInProgressCDMA() throws Exception { + public void conferenceInProgressCDMA() { // If two calls are being conferenced and updateHeadsetWithCallState runs while this is // still occurring, it will look like there is an active and held BluetoothCall still while // we are transitioning into a conference. // BluetoothCall has been put into a CDMA "conference" with one BluetoothCall on hold. - ArrayList calls = new ArrayList<>(); BluetoothCall parentCall = createActiveCall(UUID.randomUUID()); final BluetoothCall confCall1 = getMockCall(UUID.randomUUID()); final BluetoothCall confCall2 = createHeldCall(UUID.randomUUID()); - calls.add(parentCall); - calls.add(confCall1); - calls.add(confCall2); mBluetoothInCallService.onCallAdded(parentCall); mBluetoothInCallService.onCallAdded(confCall1); mBluetoothInCallService.onCallAdded(confCall2); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); - when(confCall1.getState()).thenReturn(Call.STATE_ACTIVE); - when(confCall2.getState()).thenReturn(Call.STATE_ACTIVE); - when(confCall1.isIncoming()).thenReturn(false); - when(confCall2.isIncoming()).thenReturn(true); - when(confCall1.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000"))); - when(confCall2.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001"))); + doReturn(List.of(parentCall, confCall1, confCall2)).when(mMockCallInfo).getBluetoothCalls(); + doReturn(Call.STATE_ACTIVE).when(confCall1).getState(); + doReturn(Call.STATE_ACTIVE).when(confCall2).getState(); + doReturn(true).when(confCall2).isIncoming(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000"))) + .when(confCall1) + .getGatewayInfo(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001"))) + .when(confCall2) + .getGatewayInfo(); addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE); addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE); - removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN); Integer confCall1Id = confCall1.getId(); - when(parentCall.getGenericConferenceActiveChildCallId()).thenReturn(confCall1Id); - when(parentCall.isConference()).thenReturn(true); + doReturn(confCall1Id).when(parentCall).getGenericConferenceActiveChildCallId(); + doReturn(true).when(parentCall).isConference(); List childrenIds = Arrays.asList(confCall1.getId(), confCall2.getId()); - when(parentCall.getChildrenIds()).thenReturn(childrenIds); + doReturn(childrenIds).when(parentCall).getChildrenIds(); // Add links from child calls to parent Integer parentId = parentCall.getId(); - when(confCall1.getParentId()).thenReturn(parentId); - when(confCall2.getParentId()).thenReturn(parentId); + doReturn(parentId).when(confCall1).getParentId(); + doReturn(parentId).when(confCall2).getParentId(); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.queryPhoneState(); @@ -397,7 +326,7 @@ public class BluetoothInCallServiceTest { .phoneStateChanged( eq(1), eq(1), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class)); - when(parentCall.wasConferencePreviouslyMerged()).thenReturn(true); + doReturn(true).when(parentCall).wasConferencePreviouslyMerged(); List children = mBluetoothInCallService.getBluetoothCallsByIds(parentCall.getChildrenIds()); mBluetoothInCallService.getCallback(parentCall).onChildrenChanged(parentCall, children); @@ -405,7 +334,6 @@ public class BluetoothInCallServiceTest { .phoneStateChanged( eq(1), eq(0), eq(CALL_STATE_IDLE), eq(""), eq(128), nullable(String.class)); - when(mMockCallInfo.getHeldCall()).thenReturn(null); // Spurious BluetoothCall to onIsConferencedChanged. mBluetoothInCallService.getCallback(parentCall).onChildrenChanged(parentCall, children); // Make sure the BluetoothCall has only occurred collectively 2 times (not on the third) @@ -420,45 +348,43 @@ public class BluetoothInCallServiceTest { } @Test - public void testListCurrentCallsCdmaHold() throws Exception { + public void listCurrentCallsCdmaHold() { // BluetoothCall has been put into a CDMA "conference" with one BluetoothCall on hold. - List calls = new ArrayList(); BluetoothCall parentCall = createActiveCall(UUID.randomUUID()); - when(parentCall.getHandle()).thenReturn(Uri.parse("tel:555-0000")); + doReturn(Uri.parse("tel:555-0000")).when(parentCall).getHandle(); final BluetoothCall foregroundCall = getMockCall(UUID.randomUUID()); - when(foregroundCall.getHandle()).thenReturn(Uri.parse("tel:555-0001")); + doReturn(Uri.parse("tel:555-0001")).when(foregroundCall).getHandle(); final BluetoothCall heldCall = createHeldCall(UUID.randomUUID()); - when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0002")); - calls.add(parentCall); - calls.add(foregroundCall); - calls.add(heldCall); + doReturn(Uri.parse("tel:555-0002")).when(heldCall).getHandle(); mBluetoothInCallService.onCallAdded(parentCall); mBluetoothInCallService.onCallAdded(foregroundCall); mBluetoothInCallService.onCallAdded(heldCall); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); - when(foregroundCall.getState()).thenReturn(Call.STATE_ACTIVE); - when(heldCall.getState()).thenReturn(Call.STATE_ACTIVE); - when(foregroundCall.isIncoming()).thenReturn(false); - when(heldCall.isIncoming()).thenReturn(true); - when(foregroundCall.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001"))); - when(heldCall.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0002"))); + doReturn(List.of(parentCall, foregroundCall, heldCall)) + .when(mMockCallInfo) + .getBluetoothCalls(); + doReturn(Call.STATE_ACTIVE).when(foregroundCall).getState(); + doReturn(Call.STATE_ACTIVE).when(heldCall).getState(); + doReturn(true).when(heldCall).isIncoming(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001"))) + .when(foregroundCall) + .getGatewayInfo(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0002"))) + .when(heldCall) + .getGatewayInfo(); addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE); addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE); - removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN); Integer foregroundCallId = foregroundCall.getId(); - when(parentCall.getGenericConferenceActiveChildCallId()).thenReturn(foregroundCallId); - when(parentCall.isConference()).thenReturn(true); + doReturn(foregroundCallId).when(parentCall).getGenericConferenceActiveChildCallId(); + doReturn(true).when(parentCall).isConference(); List childrenIds = Arrays.asList(foregroundCall.getId(), heldCall.getId()); - when(parentCall.getChildrenIds()).thenReturn(childrenIds); + doReturn(childrenIds).when(parentCall).getChildrenIds(); // Add links from child calls to parent Integer parentId = parentCall.getId(); - when(foregroundCall.getParentId()).thenReturn(parentId); - when(heldCall.getParentId()).thenReturn(parentId); - when(parentCall.hasProperty(Call.Details.PROPERTY_GENERIC_CONFERENCE)).thenReturn(true); + doReturn(parentId).when(foregroundCall).getParentId(); + doReturn(parentId).when(heldCall).getParentId(); + doReturn(true).when(parentCall).hasProperty(Call.Details.PROPERTY_GENERIC_CONFERENCE); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); @@ -485,43 +411,37 @@ public class BluetoothInCallServiceTest { } @Test - public void testListCurrentCallsCdmaConference() throws Exception { + public void listCurrentCallsCdmaConference() { // BluetoothCall is in a true CDMA conference - ArrayList calls = new ArrayList<>(); BluetoothCall parentCall = createActiveCall(UUID.randomUUID()); final BluetoothCall confCall1 = getMockCall(UUID.randomUUID()); final BluetoothCall confCall2 = createHeldCall(UUID.randomUUID()); - when(parentCall.getHandle()).thenReturn(Uri.parse("tel:555-0000")); - when(confCall1.getHandle()).thenReturn(Uri.parse("tel:555-0001")); - when(confCall2.getHandle()).thenReturn(Uri.parse("tel:555-0002")); - calls.add(parentCall); - calls.add(confCall1); - calls.add(confCall2); + doReturn(Uri.parse("tel:555-0000")).when(parentCall).getHandle(); + doReturn(Uri.parse("tel:555-0001")).when(confCall1).getHandle(); + doReturn(Uri.parse("tel:555-0002")).when(confCall2).getHandle(); mBluetoothInCallService.onCallAdded(parentCall); mBluetoothInCallService.onCallAdded(confCall1); mBluetoothInCallService.onCallAdded(confCall2); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); - when(confCall1.getState()).thenReturn(Call.STATE_ACTIVE); - when(confCall2.getState()).thenReturn(Call.STATE_ACTIVE); - when(confCall1.isIncoming()).thenReturn(false); - when(confCall2.isIncoming()).thenReturn(true); - when(confCall1.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000"))); - when(confCall2.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001"))); - removeCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE); - removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN); - when(parentCall.wasConferencePreviouslyMerged()).thenReturn(true); - // when(parentCall.getConferenceLevelActiveCall()).thenReturn(confCall1); - when(parentCall.isConference()).thenReturn(true); + doReturn(List.of(parentCall, confCall1, confCall2)).when(mMockCallInfo).getBluetoothCalls(); + doReturn(Call.STATE_ACTIVE).when(confCall1).getState(); + doReturn(Call.STATE_ACTIVE).when(confCall2).getState(); + doReturn(true).when(confCall2).isIncoming(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000"))) + .when(confCall1) + .getGatewayInfo(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001"))) + .when(confCall2) + .getGatewayInfo(); + doReturn(true).when(parentCall).wasConferencePreviouslyMerged(); + doReturn(true).when(parentCall).isConference(); List childrenIds = Arrays.asList(confCall1.getId(), confCall2.getId()); - when(parentCall.getChildrenIds()).thenReturn(childrenIds); + doReturn(childrenIds).when(parentCall).getChildrenIds(); // Add links from child calls to parent Integer parentId = parentCall.getId(); - when(confCall1.getParentId()).thenReturn(parentId); - when(confCall2.getParentId()).thenReturn(parentId); - when(parentCall.hasProperty(Call.Details.PROPERTY_GENERIC_CONFERENCE)).thenReturn(true); + doReturn(parentId).when(confCall1).getParentId(); + doReturn(parentId).when(confCall2).getParentId(); + doReturn(true).when(parentCall).hasProperty(Call.Details.PROPERTY_GENERIC_CONFERENCE); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); @@ -548,22 +468,20 @@ public class BluetoothInCallServiceTest { } @Test - public void testWaitingCallClccResponse() throws Exception { - ArrayList calls = new ArrayList<>(); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + public void waitingCallClccResponse() { + BluetoothCall waitingCall = createRingingCall(UUID.randomUUID()); + doReturn(List.of(waitingCall)).when(mMockCallInfo).getBluetoothCalls(); // This test does not define a value for getForegroundCall(), so this ringing // BluetoothCall will be treated as if it is a waiting BluetoothCall // when listCurrentCalls() is invoked. - BluetoothCall waitingCall = createRingingCall(UUID.randomUUID()); - calls.add(waitingCall); mBluetoothInCallService.onCallAdded(waitingCall); - when(waitingCall.isIncoming()).thenReturn(true); - when(waitingCall.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000"))); - when(waitingCall.getState()).thenReturn(Call.STATE_RINGING); - when(waitingCall.isConference()).thenReturn(false); - when(waitingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000")); + doReturn(true).when(waitingCall).isIncoming(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000"))) + .when(waitingCall) + .getGatewayInfo(); + doReturn(Call.STATE_RINGING).when(waitingCall).getState(); + doReturn(Uri.parse("tel:555-0000")).when(waitingCall).getHandle(); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); @@ -589,20 +507,17 @@ public class BluetoothInCallServiceTest { } @Test - public void testNewCallClccResponse() throws Exception { - ArrayList calls = new ArrayList<>(); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + public void newCallClccResponse() { BluetoothCall newCall = createForegroundCall(UUID.randomUUID()); - calls.add(newCall); + doReturn(List.of(newCall)).when(mMockCallInfo).getBluetoothCalls(); mBluetoothInCallService.onCallAdded(newCall); - when(newCall.getState()).thenReturn(Call.STATE_NEW); - when(newCall.isConference()).thenReturn(false); + doReturn(Call.STATE_NEW).when(newCall).getState(); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0); - verify(mMockBluetoothHeadset, times(1)) + verify(mMockBluetoothHeadset) .clccResponse( anyInt(), anyInt(), @@ -614,23 +529,20 @@ public class BluetoothInCallServiceTest { } @Test - public void testListCurrentCallsCallHandleChanged() throws Exception { - mBluetoothInCallService.mTelephonyManager = mMockTelephonyManager; - when(mMockTelephonyManager.getNetworkCountryIso()).thenReturn(""); + public void listCurrentCallsCallHandleChanged() { + doReturn("").when(mMockTelephonyManager).getNetworkCountryIso(); - ArrayList calls = new ArrayList<>(); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); BluetoothCall activeCall = createForegroundCall(UUID.randomUUID()); - calls.add(activeCall); + doReturn(List.of(activeCall)).when(mMockCallInfo).getBluetoothCalls(); mBluetoothInCallService.onCallAdded(activeCall); - when(activeCall.getState()).thenReturn(Call.STATE_ACTIVE); - when(activeCall.isIncoming()).thenReturn(true); - when(activeCall.isConference()).thenReturn(false); - when(activeCall.getHandle()).thenReturn(Uri.parse("tel:2135550000")); + doReturn(Call.STATE_ACTIVE).when(activeCall).getState(); + doReturn(true).when(activeCall).isIncoming(); + doReturn(Uri.parse("tel:2135550000")).when(activeCall).getHandle(); Log.w(TAG, "call handle" + Uri.parse("tel:2135550000")); - when(activeCall.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:2135550000"))); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:2135550000"))) + .when(activeCall) + .getGatewayInfo(); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); @@ -645,7 +557,7 @@ public class BluetoothInCallServiceTest { PhoneNumberUtils.TOA_Unknown); // call handle changed - when(activeCall.getHandle()).thenReturn(Uri.parse("tel:213-555-0000")); + doReturn(Uri.parse("tel:213-555-0000")).when(activeCall).getHandle(); clearInvocations(mMockBluetoothHeadset); Log.w(TAG, "call handle" + Uri.parse("tel:213-555-0000")); mBluetoothInCallService.listCurrentCalls(); @@ -661,19 +573,17 @@ public class BluetoothInCallServiceTest { } @Test - public void testRingingCallClccResponse() throws Exception { - ArrayList calls = new ArrayList<>(); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + public void ringingCallClccResponse() { BluetoothCall ringingCall = createForegroundCall(UUID.randomUUID()); - calls.add(ringingCall); + doReturn(List.of(ringingCall)).when(mMockCallInfo).getBluetoothCalls(); mBluetoothInCallService.onCallAdded(ringingCall); - when(ringingCall.getState()).thenReturn(Call.STATE_RINGING); - when(ringingCall.isIncoming()).thenReturn(true); - when(ringingCall.isConference()).thenReturn(false); - when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000")); - when(ringingCall.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000"))); + doReturn(Call.STATE_RINGING).when(ringingCall).getState(); + doReturn(true).when(ringingCall).isIncoming(); + doReturn(Uri.parse("tel:555-0000")).when(ringingCall).getHandle(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000"))) + .when(ringingCall) + .getGatewayInfo(); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); @@ -699,19 +609,19 @@ public class BluetoothInCallServiceTest { } @Test - public void testCallClccCache() throws Exception { - ArrayList calls = new ArrayList<>(); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + public void callClccCache() { + List calls = new ArrayList<>(); + doReturn(calls).when(mMockCallInfo).getBluetoothCalls(); BluetoothCall ringingCall = createForegroundCall(UUID.randomUUID()); calls.add(ringingCall); mBluetoothInCallService.onCallAdded(ringingCall); - when(ringingCall.getState()).thenReturn(Call.STATE_RINGING); - when(ringingCall.isIncoming()).thenReturn(true); - when(ringingCall.isConference()).thenReturn(false); - when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:5550000")); - when(ringingCall.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:5550000"))); + doReturn(Call.STATE_RINGING).when(ringingCall).getState(); + doReturn(true).when(ringingCall).isIncoming(); + doReturn(Uri.parse("tel:5550000")).when(ringingCall).getHandle(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:5550000"))) + .when(ringingCall) + .getGatewayInfo(); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); @@ -726,17 +636,17 @@ public class BluetoothInCallServiceTest { PhoneNumberUtils.TOA_Unknown); // Test Caching of old BluetoothCall indices in clcc - when(ringingCall.getState()).thenReturn(Call.STATE_ACTIVE); + doReturn(Call.STATE_ACTIVE).when(ringingCall).getState(); BluetoothCall newHoldingCall = createHeldCall(UUID.randomUUID()); calls.add(0, newHoldingCall); mBluetoothInCallService.onCallAdded(newHoldingCall); - when(newHoldingCall.getState()).thenReturn(Call.STATE_HOLDING); - when(newHoldingCall.isIncoming()).thenReturn(true); - when(newHoldingCall.isConference()).thenReturn(false); - when(newHoldingCall.getHandle()).thenReturn(Uri.parse("tel:555-0001")); - when(newHoldingCall.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001"))); + doReturn(Call.STATE_HOLDING).when(newHoldingCall).getState(); + doReturn(true).when(newHoldingCall).isIncoming(); + doReturn(Uri.parse("tel:555-0001")).when(newHoldingCall).getHandle(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001"))) + .when(newHoldingCall) + .getGatewayInfo(); mBluetoothInCallService.listCurrentCalls(); verify(mMockBluetoothHeadset) @@ -749,19 +659,16 @@ public class BluetoothInCallServiceTest { } @Test - public void testAlertingCallClccResponse() throws Exception { - ArrayList calls = new ArrayList<>(); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + public void alertingCallClccResponse() { BluetoothCall dialingCall = createForegroundCall(UUID.randomUUID()); - calls.add(dialingCall); + doReturn(List.of(dialingCall)).when(mMockCallInfo).getBluetoothCalls(); mBluetoothInCallService.onCallAdded(dialingCall); - when(dialingCall.getState()).thenReturn(Call.STATE_DIALING); - when(dialingCall.isIncoming()).thenReturn(false); - when(dialingCall.isConference()).thenReturn(false); - when(dialingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000")); - when(dialingCall.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000"))); + doReturn(Call.STATE_DIALING).when(dialingCall).getState(); + doReturn(Uri.parse("tel:555-0000")).when(dialingCall).getHandle(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000"))) + .when(dialingCall) + .getGatewayInfo(); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); @@ -787,29 +694,28 @@ public class BluetoothInCallServiceTest { } @Test - public void testHoldingCallClccResponse() throws Exception { + public void holdingCallClccResponse() { ArrayList calls = new ArrayList<>(); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + doReturn(calls).when(mMockCallInfo).getBluetoothCalls(); BluetoothCall dialingCall = createForegroundCall(UUID.randomUUID()); calls.add(dialingCall); mBluetoothInCallService.onCallAdded(dialingCall); - when(dialingCall.getState()).thenReturn(Call.STATE_DIALING); - when(dialingCall.isIncoming()).thenReturn(false); - when(dialingCall.isConference()).thenReturn(false); - when(dialingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000")); - when(dialingCall.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000"))); + doReturn(Call.STATE_DIALING).when(dialingCall).getState(); + doReturn(Uri.parse("tel:555-0000")).when(dialingCall).getHandle(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0000"))) + .when(dialingCall) + .getGatewayInfo(); BluetoothCall holdingCall = createHeldCall(UUID.randomUUID()); calls.add(holdingCall); mBluetoothInCallService.onCallAdded(holdingCall); - when(holdingCall.getState()).thenReturn(Call.STATE_HOLDING); - when(holdingCall.isIncoming()).thenReturn(true); - when(holdingCall.isConference()).thenReturn(false); - when(holdingCall.getHandle()).thenReturn(Uri.parse("tel:555-0001")); - when(holdingCall.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001"))); + doReturn(Call.STATE_HOLDING).when(holdingCall).getState(); + doReturn(true).when(holdingCall).isIncoming(); + doReturn(Uri.parse("tel:555-0001")).when(holdingCall).getHandle(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001"))) + .when(holdingCall) + .getGatewayInfo(); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); @@ -838,18 +744,16 @@ public class BluetoothInCallServiceTest { } @Test - public void testListCurrentCallsImsConference() throws Exception { - ArrayList calls = new ArrayList<>(); + public void listCurrentCallsImsConference() { BluetoothCall parentCall = createActiveCall(UUID.randomUUID()); addCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN); - when(parentCall.isConference()).thenReturn(true); - when(parentCall.getState()).thenReturn(Call.STATE_ACTIVE); - when(parentCall.isIncoming()).thenReturn(true); - when(parentCall.getHandle()).thenReturn(Uri.parse("tel:555-0000")); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + doReturn(true).when(parentCall).isConference(); + doReturn(Call.STATE_ACTIVE).when(parentCall).getState(); + doReturn(true).when(parentCall).isIncoming(); + doReturn(Uri.parse("tel:555-0000")).when(parentCall).getHandle(); + doReturn(List.of(parentCall)).when(mMockCallInfo).getBluetoothCalls(); - calls.add(parentCall); mBluetoothInCallService.onCallAdded(parentCall); clearInvocations(mMockBluetoothHeadset); @@ -868,36 +772,34 @@ public class BluetoothInCallServiceTest { } @Test - public void testListCurrentCallsHeldImsCepConference() throws Exception { - ArrayList calls = new ArrayList<>(); + public void listCurrentCallsHeldImsCepConference() { BluetoothCall parentCall = createHeldCall(UUID.randomUUID()); BluetoothCall childCall1 = createActiveCall(UUID.randomUUID()); BluetoothCall childCall2 = createActiveCall(UUID.randomUUID()); - when(parentCall.getHandle()).thenReturn(Uri.parse("tel:555-0000")); - when(childCall1.getHandle()).thenReturn(Uri.parse("tel:555-0001")); - when(childCall2.getHandle()).thenReturn(Uri.parse("tel:555-0002")); + doReturn(List.of(parentCall, childCall1, childCall2)) + .when(mMockCallInfo) + .getBluetoothCalls(); + doReturn(Uri.parse("tel:555-0000")).when(parentCall).getHandle(); + doReturn(Uri.parse("tel:555-0001")).when(childCall1).getHandle(); + doReturn(Uri.parse("tel:555-0002")).when(childCall2).getHandle(); - calls.add(parentCall); - calls.add(childCall1); - calls.add(childCall2); mBluetoothInCallService.onCallAdded(parentCall); mBluetoothInCallService.onCallAdded(childCall1); mBluetoothInCallService.onCallAdded(childCall2); addCallCapability(parentCall, Connection.CAPABILITY_MANAGE_CONFERENCE); Integer parentId = parentCall.getId(); - when(childCall1.getParentId()).thenReturn(parentId); - when(childCall2.getParentId()).thenReturn(parentId); + doReturn(parentId).when(childCall1).getParentId(); + doReturn(parentId).when(childCall2).getParentId(); List childrenIds = Arrays.asList(childCall1.getId(), childCall2.getId()); - when(parentCall.getChildrenIds()).thenReturn(childrenIds); + doReturn(childrenIds).when(parentCall).getChildrenIds(); - when(parentCall.isConference()).thenReturn(true); - when(parentCall.getState()).thenReturn(Call.STATE_HOLDING); - when(childCall1.getState()).thenReturn(Call.STATE_ACTIVE); - when(childCall2.getState()).thenReturn(Call.STATE_ACTIVE); - when(parentCall.hasProperty(Call.Details.PROPERTY_GENERIC_CONFERENCE)).thenReturn(true); - when(parentCall.isIncoming()).thenReturn(true); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + doReturn(true).when(parentCall).isConference(); + doReturn(Call.STATE_HOLDING).when(parentCall).getState(); + doReturn(Call.STATE_ACTIVE).when(childCall1).getState(); + doReturn(Call.STATE_ACTIVE).when(childCall2).getState(); + doReturn(true).when(parentCall).hasProperty(Call.Details.PROPERTY_GENERIC_CONFERENCE); + doReturn(true).when(parentCall).isIncoming(); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); @@ -924,21 +826,17 @@ public class BluetoothInCallServiceTest { } @Test - public void testListCurrentCallsConferenceGetChildrenIsEmpty() throws Exception { - ArrayList calls = new ArrayList<>(); + public void listCurrentCallsConferenceGetChildrenIsEmpty() { BluetoothCall conferenceCall = createActiveCall(UUID.randomUUID()); - when(conferenceCall.getHandle()).thenReturn(Uri.parse("tel:555-1234")); + doReturn(List.of(conferenceCall)).when(mMockCallInfo).getBluetoothCalls(); + doReturn(Uri.parse("tel:555-1234")).when(conferenceCall).getHandle(); addCallCapability(conferenceCall, Connection.CAPABILITY_MANAGE_CONFERENCE); - when(conferenceCall.isConference()).thenReturn(true); - when(conferenceCall.getState()).thenReturn(Call.STATE_ACTIVE); - when(conferenceCall.hasProperty(Call.Details.PROPERTY_GENERIC_CONFERENCE)).thenReturn(true); - when(conferenceCall.can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN)) - .thenReturn(false); - when(conferenceCall.isIncoming()).thenReturn(true); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + doReturn(true).when(conferenceCall).isConference(); + doReturn(Call.STATE_ACTIVE).when(conferenceCall).getState(); + doReturn(true).when(conferenceCall).hasProperty(Call.Details.PROPERTY_GENERIC_CONFERENCE); + doReturn(true).when(conferenceCall).isIncoming(); - calls.add(conferenceCall); mBluetoothInCallService.onCallAdded(conferenceCall); clearInvocations(mMockBluetoothHeadset); @@ -948,36 +846,34 @@ public class BluetoothInCallServiceTest { } @Test - public void testListCurrentCallsConferenceEmptyChildrenInference() throws Exception { - mBluetoothInCallService.mTelephonyManager = mMockTelephonyManager; - when(mMockTelephonyManager.getNetworkCountryIso()).thenReturn(""); + public void listCurrentCallsConferenceEmptyChildrenInference() { + doReturn("").when(mMockTelephonyManager).getNetworkCountryIso(); - ArrayList calls = new ArrayList<>(); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + List calls = new ArrayList<>(); + doReturn(calls).when(mMockCallInfo).getBluetoothCalls(); // active call is added BluetoothCall activeCall = createActiveCall(UUID.randomUUID()); calls.add(activeCall); mBluetoothInCallService.onCallAdded(activeCall); - when(activeCall.getState()).thenReturn(Call.STATE_ACTIVE); - when(activeCall.isIncoming()).thenReturn(false); - when(activeCall.isConference()).thenReturn(false); - when(activeCall.getHandle()).thenReturn(Uri.parse("tel:555-0001")); - when(activeCall.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001"))); + doReturn(Call.STATE_ACTIVE).when(activeCall).getState(); + doReturn(Uri.parse("tel:555-0001")).when(activeCall).getHandle(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001"))) + .when(activeCall) + .getGatewayInfo(); // holding call is added BluetoothCall holdingCall = createHeldCall(UUID.randomUUID()); calls.add(holdingCall); mBluetoothInCallService.onCallAdded(holdingCall); - when(holdingCall.getState()).thenReturn(Call.STATE_HOLDING); - when(holdingCall.isIncoming()).thenReturn(true); - when(holdingCall.isConference()).thenReturn(false); - when(holdingCall.getHandle()).thenReturn(Uri.parse("tel:555-0002")); - when(holdingCall.getGatewayInfo()) - .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0002"))); + doReturn(Call.STATE_HOLDING).when(holdingCall).getState(); + doReturn(true).when(holdingCall).isIncoming(); + doReturn(Uri.parse("tel:555-0002")).when(holdingCall).getHandle(); + doReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0002"))) + .when(holdingCall) + .getGatewayInfo(); // needs to have at least one CLCC response before merge to enable call inference clearInvocations(mMockBluetoothHeadset); @@ -992,22 +888,20 @@ public class BluetoothInCallServiceTest { // calls merged for conference call DisconnectCause cause = new DisconnectCause(DisconnectCause.OTHER); - when(activeCall.getDisconnectCause()).thenReturn(cause); - when(holdingCall.getDisconnectCause()).thenReturn(cause); + doReturn(cause).when(activeCall).getDisconnectCause(); + doReturn(cause).when(holdingCall).getDisconnectCause(); mBluetoothInCallService.onCallRemoved(activeCall, true); mBluetoothInCallService.onCallRemoved(holdingCall, true); BluetoothCall conferenceCall = createActiveCall(UUID.randomUUID()); addCallCapability(conferenceCall, Connection.CAPABILITY_MANAGE_CONFERENCE); - when(conferenceCall.getHandle()).thenReturn(Uri.parse("tel:555-1234")); - when(conferenceCall.isConference()).thenReturn(true); - when(conferenceCall.getState()).thenReturn(Call.STATE_ACTIVE); - when(conferenceCall.hasProperty(Call.Details.PROPERTY_GENERIC_CONFERENCE)).thenReturn(true); - when(conferenceCall.can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN)) - .thenReturn(false); - when(conferenceCall.isIncoming()).thenReturn(true); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + doReturn(Uri.parse("tel:555-1234")).when(conferenceCall).getHandle(); + doReturn(true).when(conferenceCall).isConference(); + doReturn(Call.STATE_ACTIVE).when(conferenceCall).getState(); + doReturn(true).when(conferenceCall).hasProperty(Call.Details.PROPERTY_GENERIC_CONFERENCE); + doReturn(true).when(conferenceCall).isIncoming(); + doReturn(calls).when(mMockCallInfo).getBluetoothCalls(); // parent call arrived, but children have not, then do inference on children calls.add(conferenceCall); @@ -1026,12 +920,12 @@ public class BluetoothInCallServiceTest { // real children arrive, no change on CLCC response calls.add(activeCall); mBluetoothInCallService.onCallAdded(activeCall); - when(activeCall.isConference()).thenReturn(true); + doReturn(true).when(activeCall).isConference(); calls.add(holdingCall); mBluetoothInCallService.onCallAdded(holdingCall); - when(holdingCall.getState()).thenReturn(Call.STATE_ACTIVE); - when(holdingCall.isConference()).thenReturn(true); - when(conferenceCall.getChildrenIds()).thenReturn(new ArrayList<>(Arrays.asList(1, 2))); + doReturn(Call.STATE_ACTIVE).when(holdingCall).getState(); + doReturn(true).when(holdingCall).isConference(); + doReturn(List.of(1, 2)).when(conferenceCall).getChildrenIds(); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); @@ -1044,8 +938,8 @@ public class BluetoothInCallServiceTest { // when call is terminated, children first removed, then parent cause = new DisconnectCause(DisconnectCause.LOCAL); - when(activeCall.getDisconnectCause()).thenReturn(cause); - when(holdingCall.getDisconnectCause()).thenReturn(cause); + doReturn(cause).when(activeCall).getDisconnectCause(); + doReturn(cause).when(holdingCall).getDisconnectCause(); mBluetoothInCallService.onCallRemoved(activeCall, true); mBluetoothInCallService.onCallRemoved(holdingCall, true); calls.remove(activeCall); @@ -1055,7 +949,7 @@ public class BluetoothInCallServiceTest { clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0); - verify(mMockBluetoothHeadset, times(1)) + verify(mMockBluetoothHeadset) .clccResponse( anyInt(), anyInt(), @@ -1066,14 +960,14 @@ public class BluetoothInCallServiceTest { anyInt()); // when parent is removed - when(conferenceCall.getDisconnectCause()).thenReturn(cause); + doReturn(cause).when(conferenceCall).getDisconnectCause(); calls.remove(conferenceCall); mBluetoothInCallService.onCallRemoved(conferenceCall, true); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.listCurrentCalls(); verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0); - verify(mMockBluetoothHeadset, times(1)) + verify(mMockBluetoothHeadset) .clccResponse( anyInt(), anyInt(), @@ -1085,9 +979,9 @@ public class BluetoothInCallServiceTest { } @Test - public void testQueryPhoneState() throws Exception { + public void queryPhoneState() { BluetoothCall ringingCall = createRingingCall(UUID.randomUUID()); - when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:5550000")); + doReturn(Uri.parse("tel:5550000")).when(ringingCall).getHandle(); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.queryPhoneState(); @@ -1103,19 +997,18 @@ public class BluetoothInCallServiceTest { } @Test - public void testCDMAConferenceQueryState() throws Exception { + public void cDMAConferenceQueryState() { BluetoothCall parentConfCall = createActiveCall(UUID.randomUUID()); final BluetoothCall confCall1 = getMockCall(UUID.randomUUID()); final BluetoothCall confCall2 = getMockCall(UUID.randomUUID()); mBluetoothInCallService.onCallAdded(confCall1); mBluetoothInCallService.onCallAdded(confCall2); - when(parentConfCall.getHandle()).thenReturn(Uri.parse("tel:555-0000")); + doReturn(Uri.parse("tel:555-0000")).when(parentConfCall).getHandle(); addCallCapability(parentConfCall, Connection.CAPABILITY_SWAP_CONFERENCE); - removeCallCapability(parentConfCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN); - when(parentConfCall.wasConferencePreviouslyMerged()).thenReturn(true); - when(parentConfCall.isConference()).thenReturn(true); + doReturn(true).when(parentConfCall).wasConferencePreviouslyMerged(); + doReturn(true).when(parentConfCall).isConference(); List childrenIds = Arrays.asList(confCall1.getId(), confCall2.getId()); - when(parentConfCall.getChildrenIds()).thenReturn(childrenIds); + doReturn(childrenIds).when(parentConfCall).getChildrenIds(); clearInvocations(mMockBluetoothHeadset); mBluetoothInCallService.queryPhoneState(); @@ -1125,7 +1018,7 @@ public class BluetoothInCallServiceTest { } @Test - public void testProcessChldTypeReleaseHeldRinging() throws Exception { + public void processChldTypeReleaseHeldRinging() { BluetoothCall ringingCall = createRingingCall(UUID.randomUUID()); Log.i("BluetoothInCallService", "asdf start " + Integer.toString(ringingCall.hashCode())); @@ -1136,7 +1029,7 @@ public class BluetoothInCallServiceTest { } @Test - public void testProcessChldTypeReleaseHeldHold() throws Exception { + public void processChldTypeReleaseHeldHold() { BluetoothCall onHoldCall = createHeldCall(UUID.randomUUID()); boolean didProcess = mBluetoothInCallService.processChld(CHLD_TYPE_RELEASEHELD); @@ -1145,7 +1038,7 @@ public class BluetoothInCallServiceTest { } @Test - public void testProcessChldReleaseActiveRinging() throws Exception { + public void processChldReleaseActiveRinging() { BluetoothCall activeCall = createActiveCall(UUID.randomUUID()); BluetoothCall ringingCall = createRingingCall(UUID.randomUUID()); @@ -1158,7 +1051,7 @@ public class BluetoothInCallServiceTest { } @Test - public void testProcessChldReleaseActiveHold() throws Exception { + public void processChldReleaseActiveHold() { BluetoothCall activeCall = createActiveCall(UUID.randomUUID()); boolean didProcess = @@ -1171,7 +1064,7 @@ public class BluetoothInCallServiceTest { } @Test - public void testProcessChldHoldActiveRinging() throws Exception { + public void processChldHoldActiveRinging() { BluetoothCall ringingCall = createRingingCall(UUID.randomUUID()); boolean didProcess = mBluetoothInCallService.processChld(CHLD_TYPE_HOLDACTIVE_ACCEPTHELD); @@ -1181,7 +1074,7 @@ public class BluetoothInCallServiceTest { } @Test - public void testProcessChldHoldActiveUnhold() throws Exception { + public void processChldHoldActiveUnhold() { BluetoothCall heldCall = createHeldCall(UUID.randomUUID()); boolean didProcess = mBluetoothInCallService.processChld(CHLD_TYPE_HOLDACTIVE_ACCEPTHELD); @@ -1191,7 +1084,7 @@ public class BluetoothInCallServiceTest { } @Test - public void testProcessChldHoldActiveHold() throws Exception { + public void processChldHoldActiveHold() { BluetoothCall activeCall = createActiveCall(UUID.randomUUID()); addCallCapability(activeCall, Connection.CAPABILITY_HOLD); @@ -1202,7 +1095,7 @@ public class BluetoothInCallServiceTest { } @Test - public void testProcessChldAddHeldToConfHolding() throws Exception { + public void processChldAddHeldToConfHolding() { BluetoothCall activeCall = createActiveCall(UUID.randomUUID()); addCallCapability(activeCall, Connection.CAPABILITY_MERGE_CONFERENCE); @@ -1213,15 +1106,14 @@ public class BluetoothInCallServiceTest { } @Test - public void testProcessChldAddHeldToConf() throws Exception { + public void processChldAddHeldToConf() { BluetoothCall activeCall = createActiveCall(UUID.randomUUID()); - removeCallCapability(activeCall, Connection.CAPABILITY_MERGE_CONFERENCE); BluetoothCall conferenceableCall = getMockCall(UUID.randomUUID()); ArrayList conferenceableCalls = new ArrayList<>(); conferenceableCalls.add(conferenceableCall.getId()); mBluetoothInCallService.onCallAdded(conferenceableCall); - when(activeCall.getConferenceableCalls()).thenReturn(conferenceableCalls); + doReturn(conferenceableCalls).when(activeCall).getConferenceableCalls(); boolean didProcess = mBluetoothInCallService.processChld(CHLD_TYPE_ADDHELDTOCONF); @@ -1230,21 +1122,19 @@ public class BluetoothInCallServiceTest { } @Test - public void testProcessChldHoldActiveSwapConference() throws Exception { + public void processChldHoldActiveSwapConference() { // Create an active CDMA BluetoothCall with a BluetoothCall on hold // and simulate a swapConference(). BluetoothCall parentCall = createActiveCall(UUID.randomUUID()); final BluetoothCall foregroundCall = getMockCall(UUID.randomUUID()); - when(foregroundCall.getHandle()).thenReturn(Uri.parse("tel:555-0001")); + doReturn(Uri.parse("tel:555-0001")).when(foregroundCall).getHandle(); final BluetoothCall heldCall = createHeldCall(UUID.randomUUID()); - when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0002")); + doReturn(Uri.parse("tel:555-0002")).when(heldCall).getHandle(); addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE); - removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN); - when(parentCall.isConference()).thenReturn(true); - when(parentCall.wasConferencePreviouslyMerged()).thenReturn(false); - when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0000")); + doReturn(true).when(parentCall).isConference(); + doReturn(Uri.parse("tel:555-0000")).when(heldCall).getHandle(); List childrenIds = Arrays.asList(foregroundCall.getId(), heldCall.getId()); - when(parentCall.getChildrenIds()).thenReturn(childrenIds); + doReturn(childrenIds).when(parentCall).getChildrenIds(); clearInvocations(mMockBluetoothHeadset); boolean didProcess = mBluetoothInCallService.processChld(CHLD_TYPE_HOLDACTIVE_ACCEPTHELD); @@ -1258,9 +1148,9 @@ public class BluetoothInCallServiceTest { // Testing the CallsManager Listener Functionality on Bluetooth @Test - public void testOnCallAddedRinging() throws Exception { + public void onCallAddedRinging() { BluetoothCall ringingCall = createRingingCall(UUID.randomUUID()); - when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000")); + doReturn(Uri.parse("tel:555000")).when(ringingCall).getHandle(); mBluetoothInCallService.onCallAdded(ringingCall); @@ -1275,10 +1165,10 @@ public class BluetoothInCallServiceTest { } @Test - public void testSilentRingingCallState() throws Exception { + public void silentRingingCallState() { BluetoothCall ringingCall = createRingingCall(UUID.randomUUID()); - when(ringingCall.isSilentRingingRequested()).thenReturn(true); - when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000")); + doReturn(true).when(ringingCall).isSilentRingingRequested(); + doReturn(Uri.parse("tel:555000")).when(ringingCall).getHandle(); mBluetoothInCallService.onCallAdded(ringingCall); @@ -1293,18 +1183,17 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnCallAddedCdmaActiveHold() throws Exception { + public void onCallAddedCdmaActiveHold() { // BluetoothCall has been put into a CDMA "conference" with one BluetoothCall on hold. BluetoothCall parentCall = createActiveCall(UUID.randomUUID()); final BluetoothCall foregroundCall = getMockCall(UUID.randomUUID()); final BluetoothCall heldCall = createHeldCall(UUID.randomUUID()); - when(foregroundCall.getHandle()).thenReturn(Uri.parse("tel:555-0001")); - when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0002")); + doReturn(Uri.parse("tel:555-0001")).when(foregroundCall).getHandle(); + doReturn(Uri.parse("tel:555-0002")).when(heldCall).getHandle(); addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE); - removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN); - when(parentCall.isConference()).thenReturn(true); + doReturn(true).when(parentCall).isConference(); List childrenIds = Arrays.asList(foregroundCall.getId(), heldCall.getId()); - when(parentCall.getChildrenIds()).thenReturn(childrenIds); + doReturn(childrenIds).when(parentCall).getChildrenIds(); mBluetoothInCallService.onCallAdded(parentCall); @@ -1314,11 +1203,11 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnCallRemoved() throws Exception { + public void onCallRemoved() { BluetoothCall activeCall = createActiveCall(UUID.randomUUID()); mBluetoothInCallService.onCallAdded(activeCall); doReturn(null).when(mMockCallInfo).getActiveCall(); - when(activeCall.getHandle()).thenReturn(Uri.parse("tel:555-0001")); + doReturn(Uri.parse("tel:555-0001")).when(activeCall).getHandle(); mBluetoothInCallService.onCallRemoved(activeCall, true /* forceRemoveCallback */); @@ -1328,13 +1217,13 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnDetailsChangeExternalRemovesCall() throws Exception { + public void onDetailsChangeExternalRemovesCall() { BluetoothCall activeCall = createActiveCall(UUID.randomUUID()); mBluetoothInCallService.onCallAdded(activeCall); doReturn(null).when(mMockCallInfo).getActiveCall(); - when(activeCall.getHandle()).thenReturn(Uri.parse("tel:555-0001")); + doReturn(Uri.parse("tel:555-0001")).when(activeCall).getHandle(); - when(activeCall.isExternalCall()).thenReturn(true); + doReturn(true).when(activeCall).isExternalCall(); mBluetoothInCallService.getCallback(activeCall).onDetailsChanged(activeCall, null); verify(mMockBluetoothHeadset) @@ -1343,17 +1232,14 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnDetailsChangeExternalAddsCall() throws Exception { + public void onDetailsChangeExternalAddsCall() { BluetoothCall activeCall = createActiveCall(UUID.randomUUID()); mBluetoothInCallService.onCallAdded(activeCall); - when(activeCall.getHandle()).thenReturn(Uri.parse("tel:555-0001")); + doReturn(Uri.parse("tel:555-0001")).when(activeCall).getHandle(); BluetoothInCallService.CallStateCallback callBack = mBluetoothInCallService.getCallback(activeCall); - when(activeCall.isExternalCall()).thenReturn(true); - callBack.onDetailsChanged(activeCall, null); - - when(activeCall.isExternalCall()).thenReturn(false); + doReturn(true).when(activeCall).isExternalCall(); callBack.onDetailsChanged(activeCall, null); verify(mMockBluetoothHeadset) @@ -1362,16 +1248,15 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnCallStateChangedConnectingCall() throws Exception { + public void onCallStateChangedConnectingCall() { BluetoothCall activeCall = getMockCall(UUID.randomUUID()); BluetoothCall connectingCall = getMockCall(UUID.randomUUID()); - when(connectingCall.getState()).thenReturn(Call.STATE_CONNECTING); - ArrayList calls = new ArrayList<>(); - calls.add(connectingCall); - calls.add(activeCall); + doReturn(Call.STATE_CONNECTING).when(connectingCall).getState(); + + doReturn(List.of(connectingCall, activeCall)).when(mMockCallInfo).getBluetoothCalls(); + mBluetoothInCallService.onCallAdded(connectingCall); mBluetoothInCallService.onCallAdded(activeCall); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); mBluetoothInCallService .getCallback(activeCall) @@ -1388,9 +1273,9 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnCallAddedAudioProcessing() throws Exception { + public void onCallAddedAudioProcessing() { BluetoothCall call = getMockCall(UUID.randomUUID()); - when(call.getState()).thenReturn(Call.STATE_AUDIO_PROCESSING); + doReturn(Call.STATE_AUDIO_PROCESSING).when(call).getState(); mBluetoothInCallService.onCallAdded(call); verify(mMockBluetoothHeadset, never()) @@ -1404,9 +1289,9 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnCallStateChangedRingingToAudioProcessing() throws Exception { + public void onCallStateChangedRingingToAudioProcessing() { BluetoothCall ringingCall = createRingingCall(UUID.randomUUID()); - when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000")); + doReturn(Uri.parse("tel:555000")).when(ringingCall).getHandle(); mBluetoothInCallService.onCallAdded(ringingCall); @@ -1419,8 +1304,8 @@ public class BluetoothInCallServiceTest { eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class)); - when(ringingCall.getState()).thenReturn(Call.STATE_AUDIO_PROCESSING); - when(mMockCallInfo.getRingingOrSimulatedRingingCall()).thenReturn(null); + doReturn(Call.STATE_AUDIO_PROCESSING).when(ringingCall).getState(); + doReturn(null).when(mMockCallInfo).getRingingOrSimulatedRingingCall(); mBluetoothInCallService .getCallback(ringingCall) @@ -1432,9 +1317,9 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnCallStateChangedAudioProcessingToSimulatedRinging() throws Exception { + public void onCallStateChangedAudioProcessingToSimulatedRinging() { BluetoothCall ringingCall = createRingingCall(UUID.randomUUID()); - when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000")); + doReturn(Uri.parse("tel:555-0000")).when(ringingCall).getHandle(); mBluetoothInCallService.onCallAdded(ringingCall); mBluetoothInCallService .getCallback(ringingCall) @@ -1451,9 +1336,9 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnCallStateChangedAudioProcessingToActive() throws Exception { + public void onCallStateChangedAudioProcessingToActive() { BluetoothCall activeCall = createActiveCall(UUID.randomUUID()); - when(activeCall.getState()).thenReturn(Call.STATE_ACTIVE); + doReturn(Call.STATE_ACTIVE).when(activeCall).getState(); mBluetoothInCallService.onCallAdded(activeCall); mBluetoothInCallService .getCallback(activeCall) @@ -1465,7 +1350,7 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnCallStateChangedDialing() throws Exception { + public void onCallStateChangedDialing() { BluetoothCall activeCall = createActiveCall(UUID.randomUUID()); // make "mLastState" STATE_CONNECTING @@ -1489,7 +1374,7 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnCallStateChangedAlerting() throws Exception { + public void onCallStateChangedAlerting() { BluetoothCall outgoingCall = createOutgoingCall(UUID.randomUUID()); mBluetoothInCallService.onCallAdded(outgoingCall); mBluetoothInCallService @@ -1515,7 +1400,7 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnCallStateChangedDisconnected() throws Exception { + public void onCallStateChangedDisconnected() { BluetoothCall disconnectedCall = createDisconnectedCall(UUID.randomUUID()); doReturn(true).when(mMockCallInfo).hasOnlyDisconnectedCalls(); mBluetoothInCallService.onCallAdded(disconnectedCall); @@ -1533,9 +1418,9 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnCallStateChanged() throws Exception { + public void onCallStateChanged() { BluetoothCall ringingCall = createRingingCall(UUID.randomUUID()); - when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000")); + doReturn(Uri.parse("tel:555-0000")).when(ringingCall).getHandle(); mBluetoothInCallService.onCallAdded(ringingCall); verify(mMockBluetoothHeadset) @@ -1549,7 +1434,7 @@ public class BluetoothInCallServiceTest { // Switch to active doReturn(null).when(mMockCallInfo).getRingingOrSimulatedRingingCall(); - when(mMockCallInfo.getActiveCall()).thenReturn(ringingCall); + doReturn(ringingCall).when(mMockCallInfo).getActiveCall(); mBluetoothInCallService .getCallback(ringingCall) @@ -1561,9 +1446,9 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnCallStateChangedGSMSwap() throws Exception { + public void onCallStateChangedGSMSwap() { BluetoothCall heldCall = createHeldCall(UUID.randomUUID()); - when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0000")); + doReturn(Uri.parse("tel:555-0000")).when(heldCall).getHandle(); mBluetoothInCallService.onCallAdded(heldCall); doReturn(2).when(mMockCallInfo).getNumHeldCalls(); @@ -1581,7 +1466,7 @@ public class BluetoothInCallServiceTest { } @Test - public void testOnParentOnChildrenChanged() throws Exception { + public void onParentOnChildrenChanged() { // Start with two calls that are being merged into a CDMA conference call. The // onIsConferencedChanged method will be called multiple times during the call. Make sure // that the bluetooth phone state is updated properly. @@ -1592,18 +1477,16 @@ public class BluetoothInCallServiceTest { mBluetoothInCallService.onCallAdded(activeCall); mBluetoothInCallService.onCallAdded(heldCall); Integer parentId = parentCall.getId(); - when(activeCall.getParentId()).thenReturn(parentId); - when(heldCall.getParentId()).thenReturn(parentId); + doReturn(parentId).when(activeCall).getParentId(); + doReturn(parentId).when(heldCall).getParentId(); - ArrayList calls = new ArrayList<>(); + List calls = new ArrayList<>(); calls.add(activeCall.getId()); - when(parentCall.getChildrenIds()).thenReturn(calls); - when(parentCall.isConference()).thenReturn(true); + doReturn(calls).when(parentCall).getChildrenIds(); + doReturn(true).when(parentCall).isConference(); - removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN); addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE); - when(parentCall.wasConferencePreviouslyMerged()).thenReturn(false); clearInvocations(mMockBluetoothHeadset); // Be sure that onIsConferencedChanged rejects spurious changes during set up of @@ -1653,9 +1536,9 @@ public class BluetoothInCallServiceTest { } @Test - public void testBluetoothAdapterReceiver() throws Exception { + public void bluetoothAdapterReceiver() { BluetoothCall ringingCall = createRingingCall(UUID.randomUUID()); - when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:5550000")); + doReturn(Uri.parse("tel:5550000")).when(ringingCall).getHandle(); Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED); intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON); @@ -1676,16 +1559,7 @@ public class BluetoothInCallServiceTest { } @Test - public void testClear() { - doNothing() - .when(mContext) - .unregisterReceiver(any(BluetoothInCallService.BluetoothAdapterReceiver.class)); - mBluetoothInCallService.attachBaseContext(mContext); - mBluetoothInCallService.mBluetoothAdapterReceiver = - mBluetoothInCallService.new BluetoothAdapterReceiver(); - Assert.assertNotNull(mBluetoothInCallService.mBluetoothAdapterReceiver); - Assert.assertNotNull(mBluetoothInCallService.mBluetoothHeadset); - + public void clear() { mBluetoothInCallService.clear(); Assert.assertNull(mBluetoothInCallService.mBluetoothAdapterReceiver); @@ -1693,107 +1567,113 @@ public class BluetoothInCallServiceTest { } @Test - public void testGetBearerTechnology() { - mBluetoothInCallService.mTelephonyManager = mMockTelephonyManager; + public void getBearerTechnology() { - when(mMockTelephonyManager.getDataNetworkType()) - .thenReturn(TelephonyManager.NETWORK_TYPE_GSM); + doReturn(TelephonyManager.NETWORK_TYPE_GSM) + .when(mMockTelephonyManager) + .getDataNetworkType(); Assert.assertEquals( mBluetoothInCallService.getBearerTechnology(), BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_GSM); - when(mMockTelephonyManager.getDataNetworkType()) - .thenReturn(TelephonyManager.NETWORK_TYPE_GPRS); + doReturn(TelephonyManager.NETWORK_TYPE_GPRS) + .when(mMockTelephonyManager) + .getDataNetworkType(); Assert.assertEquals( mBluetoothInCallService.getBearerTechnology(), BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_2G); - when(mMockTelephonyManager.getDataNetworkType()) - .thenReturn(TelephonyManager.NETWORK_TYPE_EVDO_B); + doReturn(TelephonyManager.NETWORK_TYPE_EVDO_B) + .when(mMockTelephonyManager) + .getDataNetworkType(); Assert.assertEquals( mBluetoothInCallService.getBearerTechnology(), BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_3G); - when(mMockTelephonyManager.getDataNetworkType()) - .thenReturn(TelephonyManager.NETWORK_TYPE_TD_SCDMA); + doReturn(TelephonyManager.NETWORK_TYPE_TD_SCDMA) + .when(mMockTelephonyManager) + .getDataNetworkType(); Assert.assertEquals( mBluetoothInCallService.getBearerTechnology(), BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_WCDMA); - when(mMockTelephonyManager.getDataNetworkType()) - .thenReturn(TelephonyManager.NETWORK_TYPE_LTE); + doReturn(TelephonyManager.NETWORK_TYPE_LTE) + .when(mMockTelephonyManager) + .getDataNetworkType(); Assert.assertEquals( mBluetoothInCallService.getBearerTechnology(), BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_LTE); - when(mMockTelephonyManager.getDataNetworkType()) - .thenReturn(TelephonyManager.NETWORK_TYPE_1xRTT); + doReturn(TelephonyManager.NETWORK_TYPE_1xRTT) + .when(mMockTelephonyManager) + .getDataNetworkType(); Assert.assertEquals( mBluetoothInCallService.getBearerTechnology(), BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_CDMA); - when(mMockTelephonyManager.getDataNetworkType()) - .thenReturn(TelephonyManager.NETWORK_TYPE_HSPAP); + doReturn(TelephonyManager.NETWORK_TYPE_HSPAP) + .when(mMockTelephonyManager) + .getDataNetworkType(); Assert.assertEquals( mBluetoothInCallService.getBearerTechnology(), BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_4G); - when(mMockTelephonyManager.getDataNetworkType()) - .thenReturn(TelephonyManager.NETWORK_TYPE_IWLAN); + doReturn(TelephonyManager.NETWORK_TYPE_IWLAN) + .when(mMockTelephonyManager) + .getDataNetworkType(); Assert.assertEquals( mBluetoothInCallService.getBearerTechnology(), BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_WIFI); - when(mMockTelephonyManager.getDataNetworkType()) - .thenReturn(TelephonyManager.NETWORK_TYPE_NR); + doReturn(TelephonyManager.NETWORK_TYPE_NR).when(mMockTelephonyManager).getDataNetworkType(); Assert.assertEquals( mBluetoothInCallService.getBearerTechnology(), BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_5G); - when(mMockTelephonyManager.getDataNetworkType()) - .thenReturn(TelephonyManager.NETWORK_TYPE_LTE_CA); + doReturn(TelephonyManager.NETWORK_TYPE_LTE_CA) + .when(mMockTelephonyManager) + .getDataNetworkType(); Assert.assertEquals( mBluetoothInCallService.getBearerTechnology(), BluetoothLeCallControlProxy.BEARER_TECHNOLOGY_GSM); } @Test - public void testGetTbsTerminationReason() { + public void getTbsTerminationReason() { BluetoothCall call = getMockCall(UUID.randomUUID()); - when(call.getDisconnectCause()).thenReturn(null); Assert.assertEquals( mBluetoothInCallService.getTbsTerminationReason(call), BluetoothLeCallControl.TERMINATION_REASON_FAIL); DisconnectCause cause = new DisconnectCause(DisconnectCause.BUSY, null, null, null, 1); - when(call.getDisconnectCause()).thenReturn(cause); + doReturn(cause).when(call).getDisconnectCause(); Assert.assertEquals( mBluetoothInCallService.getTbsTerminationReason(call), BluetoothLeCallControl.TERMINATION_REASON_LINE_BUSY); cause = new DisconnectCause(DisconnectCause.REJECTED, null, null, null, 1); - when(call.getDisconnectCause()).thenReturn(cause); + doReturn(cause).when(call).getDisconnectCause(); Assert.assertEquals( mBluetoothInCallService.getTbsTerminationReason(call), BluetoothLeCallControl.TERMINATION_REASON_REMOTE_HANGUP); cause = new DisconnectCause(DisconnectCause.LOCAL, null, null, null, 1); - when(call.getDisconnectCause()).thenReturn(cause); + doReturn(cause).when(call).getDisconnectCause(); mBluetoothInCallService.mIsTerminatedByClient = false; Assert.assertEquals( mBluetoothInCallService.getTbsTerminationReason(call), BluetoothLeCallControl.TERMINATION_REASON_SERVER_HANGUP); cause = new DisconnectCause(DisconnectCause.LOCAL, null, null, null, 1); - when(call.getDisconnectCause()).thenReturn(cause); + doReturn(cause).when(call).getDisconnectCause(); mBluetoothInCallService.mIsTerminatedByClient = true; Assert.assertEquals( mBluetoothInCallService.getTbsTerminationReason(call), BluetoothLeCallControl.TERMINATION_REASON_CLIENT_HANGUP); cause = new DisconnectCause(DisconnectCause.ERROR, null, null, null, 1); - when(call.getDisconnectCause()).thenReturn(cause); + doReturn(cause).when(call).getDisconnectCause(); Assert.assertEquals( mBluetoothInCallService.getTbsTerminationReason(call), BluetoothLeCallControl.TERMINATION_REASON_NETWORK_CONGESTION); @@ -1801,35 +1681,20 @@ public class BluetoothInCallServiceTest { cause = new DisconnectCause( DisconnectCause.CONNECTION_MANAGER_NOT_SUPPORTED, null, null, null, 1); - when(call.getDisconnectCause()).thenReturn(cause); + doReturn(cause).when(call).getDisconnectCause(); Assert.assertEquals( mBluetoothInCallService.getTbsTerminationReason(call), BluetoothLeCallControl.TERMINATION_REASON_INVALID_URI); cause = new DisconnectCause(DisconnectCause.ERROR, null, null, null, 1); - when(call.getDisconnectCause()).thenReturn(cause); + doReturn(cause).when(call).getDisconnectCause(); Assert.assertEquals( mBluetoothInCallService.getTbsTerminationReason(call), BluetoothLeCallControl.TERMINATION_REASON_NETWORK_CONGESTION); } @Test - public void testOnCreate() { - ApplicationInfo applicationInfo = new ApplicationInfo(); - applicationInfo.targetSdkVersion = Build.VERSION_CODES.S; - when(mContext.getApplicationInfo()).thenReturn(applicationInfo); - mBluetoothInCallService.attachBaseContext(mContext); - mBluetoothInCallService.setOnCreateCalled(false); - Assert.assertNull(mBluetoothInCallService.mBluetoothAdapterReceiver); - - mBluetoothInCallService.onCreate(); - - Assert.assertNotNull(mBluetoothInCallService.mBluetoothAdapterReceiver); - Assert.assertTrue(mBluetoothInCallService.mOnCreateCalled); - } - - @Test - public void testOnDestroy() { + public void onDestroy() { Assert.assertTrue(mBluetoothInCallService.mOnCreateCalled); mBluetoothInCallService.onDestroy(); @@ -1838,223 +1703,188 @@ public class BluetoothInCallServiceTest { } @Test - public void testLeCallControlCallback_onAcceptCall_withUnknownCallId() { - BluetoothLeCallControlProxy callControlProxy = mock(BluetoothLeCallControlProxy.class); - mBluetoothInCallService.mBluetoothLeCallControl = callControlProxy; - BluetoothLeCallControl.Callback callback = - mBluetoothInCallService.mBluetoothLeCallControlCallback; - + public void leCallControlCallback_onAcceptCall_withUnknownCallId() { int requestId = 1; UUID unknownCallId = UUID.randomUUID(); - callback.onAcceptCall(requestId, unknownCallId); + mBluetoothInCallService.mBluetoothLeCallControlCallback.onAcceptCall( + requestId, unknownCallId); - verify(callControlProxy) + verify(mLeCallControl) .requestResult(requestId, BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID); } @Test - public void testLeCallControlCallback_onTerminateCall_withUnknownCallId() { - BluetoothLeCallControlProxy callControlProxy = mock(BluetoothLeCallControlProxy.class); - mBluetoothInCallService.mBluetoothLeCallControl = callControlProxy; - BluetoothLeCallControl.Callback callback = - mBluetoothInCallService.mBluetoothLeCallControlCallback; - + public void leCallControlCallback_onTerminateCall_withUnknownCallId() { int requestId = 1; UUID unknownCallId = UUID.randomUUID(); - callback.onTerminateCall(requestId, unknownCallId); + mBluetoothInCallService.mBluetoothLeCallControlCallback.onTerminateCall( + requestId, unknownCallId); - verify(callControlProxy) + verify(mLeCallControl) .requestResult(requestId, BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID); } @Test - public void testLeCallControlCallback_onHoldCall_withUnknownCallId() { - BluetoothLeCallControlProxy callControlProxy = mock(BluetoothLeCallControlProxy.class); - mBluetoothInCallService.mBluetoothLeCallControl = callControlProxy; - BluetoothLeCallControl.Callback callback = - mBluetoothInCallService.mBluetoothLeCallControlCallback; - + public void leCallControlCallback_onHoldCall_withUnknownCallId() { int requestId = 1; UUID unknownCallId = UUID.randomUUID(); - callback.onHoldCall(requestId, unknownCallId); + mBluetoothInCallService.mBluetoothLeCallControlCallback.onHoldCall( + requestId, unknownCallId); - verify(callControlProxy) + verify(mLeCallControl) .requestResult(requestId, BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID); } @Test - public void testLeCallControlCallback_onUnholdCall_withUnknownCallId() { - BluetoothLeCallControlProxy callControlProxy = mock(BluetoothLeCallControlProxy.class); - mBluetoothInCallService.mBluetoothLeCallControl = callControlProxy; - BluetoothLeCallControl.Callback callback = - mBluetoothInCallService.mBluetoothLeCallControlCallback; - + public void leCallControlCallback_onUnholdCall_withUnknownCallId() { int requestId = 1; UUID unknownCallId = UUID.randomUUID(); - callback.onUnholdCall(requestId, unknownCallId); + mBluetoothInCallService.mBluetoothLeCallControlCallback.onUnholdCall( + requestId, unknownCallId); - verify(callControlProxy) + verify(mLeCallControl) .requestResult(requestId, BluetoothLeCallControl.RESULT_ERROR_UNKNOWN_CALL_ID); } @Test - public void testLeCallControlCallback_onJoinCalls() { - BluetoothLeCallControlProxy callControlProxy = mock(BluetoothLeCallControlProxy.class); - mBluetoothInCallService.mBluetoothLeCallControl = callControlProxy; - BluetoothLeCallControl.Callback callback = - mBluetoothInCallService.mBluetoothLeCallControlCallback; - + public void leCallControlCallback_onJoinCalls() { int requestId = 1; UUID baseCallId = UUID.randomUUID(); UUID firstJoiningCallId = UUID.randomUUID(); UUID secondJoiningCallId = UUID.randomUUID(); - List uuids = - new ArrayList<>(Arrays.asList(baseCallId, firstJoiningCallId, secondJoiningCallId)); - ArrayList calls = new ArrayList<>(); + List uuids = List.of(baseCallId, firstJoiningCallId, secondJoiningCallId); + BluetoothCall baseCall = createActiveCall(baseCallId); BluetoothCall firstCall = createRingingCall(firstJoiningCallId); BluetoothCall secondCall = createRingingCall(secondJoiningCallId); - when(baseCall.getState()).thenReturn(Call.STATE_ACTIVE); - when(firstCall.getState()).thenReturn(Call.STATE_RINGING); - when(secondCall.getState()).thenReturn(Call.STATE_RINGING); - calls.add(baseCall); - calls.add(firstCall); - calls.add(secondCall); + + doReturn(Call.STATE_ACTIVE).when(baseCall).getState(); + doReturn(Call.STATE_RINGING).when(firstCall).getState(); + doReturn(Call.STATE_RINGING).when(secondCall).getState(); + + doReturn(List.of(baseCall, firstCall, secondCall)).when(mMockCallInfo).getBluetoothCalls(); + mBluetoothInCallService.onCallAdded(baseCall); mBluetoothInCallService.onCallAdded(firstCall); mBluetoothInCallService.onCallAdded(secondCall); - when(baseCall.getHandle()).thenReturn(Uri.parse("tel:111-111")); - when(firstCall.getHandle()).thenReturn(Uri.parse("tel:222-222")); - when(secondCall.getHandle()).thenReturn(Uri.parse("tel:333-333")); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + + doReturn(Uri.parse("tel:111-111")).when(baseCall).getHandle(); + doReturn(Uri.parse("tel:222-222")).when(firstCall).getHandle(); + doReturn(Uri.parse("tel:333-333")).when(secondCall).getHandle(); doReturn(baseCall).when(mMockCallInfo).getCallByCallId(baseCallId); doReturn(firstCall).when(mMockCallInfo).getCallByCallId(firstJoiningCallId); doReturn(secondCall).when(mMockCallInfo).getCallByCallId(secondJoiningCallId); - callback.onJoinCalls(requestId, uuids); + mBluetoothInCallService.mBluetoothLeCallControlCallback.onJoinCalls(requestId, uuids); - verify(callControlProxy).requestResult(requestId, BluetoothLeCallControl.RESULT_SUCCESS); + verify(mLeCallControl).requestResult(requestId, BluetoothLeCallControl.RESULT_SUCCESS); verify(baseCall, times(2)).conference(any(BluetoothCall.class)); } @Test - public void testLeCallControlCallback_onJoinCalls_omitDoubledCalls() { - BluetoothLeCallControlProxy callControlProxy = mock(BluetoothLeCallControlProxy.class); - mBluetoothInCallService.mBluetoothLeCallControl = callControlProxy; - BluetoothLeCallControl.Callback callback = - mBluetoothInCallService.mBluetoothLeCallControlCallback; - + public void leCallControlCallback_onJoinCalls_omitDoubledCalls() { int requestId = 1; UUID baseCallId = UUID.randomUUID(); UUID firstJoiningCallId = UUID.randomUUID(); - List uuids = - new ArrayList<>(Arrays.asList(baseCallId, firstJoiningCallId, firstJoiningCallId)); - ArrayList calls = new ArrayList<>(); + List uuids = List.of(baseCallId, firstJoiningCallId); + BluetoothCall baseCall = createActiveCall(baseCallId); BluetoothCall firstCall = createRingingCall(firstJoiningCallId); - when(baseCall.getState()).thenReturn(Call.STATE_ACTIVE); - when(firstCall.getState()).thenReturn(Call.STATE_RINGING); - calls.add(baseCall); - calls.add(firstCall); + + doReturn(List.of(baseCall, firstCall)).when(mMockCallInfo).getBluetoothCalls(); + + doReturn(Call.STATE_ACTIVE).when(baseCall).getState(); + doReturn(Call.STATE_RINGING).when(firstCall).getState(); + mBluetoothInCallService.onCallAdded(baseCall); mBluetoothInCallService.onCallAdded(firstCall); - when(baseCall.getHandle()).thenReturn(Uri.parse("tel:111-111")); - when(firstCall.getHandle()).thenReturn(Uri.parse("tel:222-222")); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); - doReturn(baseCall).when(mMockCallInfo).getCallByCallId(baseCallId); - doReturn(firstCall).when(mMockCallInfo).getCallByCallId(firstJoiningCallId); + doReturn(Uri.parse("tel:111-111")).when(baseCall).getHandle(); + doReturn(Uri.parse("tel:222-222")).when(firstCall).getHandle(); - callback.onJoinCalls(requestId, uuids); + doReturn(baseCall).when(mMockCallInfo).getCallByCallId(eq(baseCallId)); + doReturn(firstCall).when(mMockCallInfo).getCallByCallId(eq(firstJoiningCallId)); - verify(callControlProxy).requestResult(requestId, BluetoothLeCallControl.RESULT_SUCCESS); - verify(baseCall, times(1)).conference(any(BluetoothCall.class)); + mBluetoothInCallService.mBluetoothLeCallControlCallback.onJoinCalls(requestId, uuids); + + verify(mLeCallControl).requestResult(requestId, BluetoothLeCallControl.RESULT_SUCCESS); + verify(baseCall).conference(any(BluetoothCall.class)); } @Test - public void testLeCallControlCallback_onJoinCalls_omitNullCalls() { - BluetoothLeCallControlProxy callControlProxy = mock(BluetoothLeCallControlProxy.class); - mBluetoothInCallService.mBluetoothLeCallControl = callControlProxy; - BluetoothLeCallControl.Callback callback = - mBluetoothInCallService.mBluetoothLeCallControlCallback; - + public void leCallControlCallback_onJoinCalls_omitNullCalls() { int requestId = 1; UUID baseCallId = UUID.randomUUID(); UUID firstJoiningCallId = UUID.randomUUID(); UUID secondJoiningCallId = UUID.randomUUID(); - List uuids = - new ArrayList<>(Arrays.asList(baseCallId, firstJoiningCallId, secondJoiningCallId)); - ArrayList calls = new ArrayList<>(); + List uuids = List.of(baseCallId, firstJoiningCallId, secondJoiningCallId); + BluetoothCall baseCall = createActiveCall(baseCallId); BluetoothCall firstCall = createRingingCall(firstJoiningCallId); BluetoothCall secondCall = createRingingCall(secondJoiningCallId); - when(baseCall.getState()).thenReturn(Call.STATE_ACTIVE); - when(firstCall.getState()).thenReturn(Call.STATE_RINGING); - when(secondCall.getState()).thenReturn(Call.STATE_RINGING); - calls.add(baseCall); - calls.add(firstCall); - calls.add(secondCall); + + doReturn(List.of(baseCall, firstCall, secondCall)).when(mMockCallInfo).getBluetoothCalls(); + + doReturn(Call.STATE_ACTIVE).when(baseCall).getState(); + doReturn(Call.STATE_RINGING).when(firstCall).getState(); + doReturn(Call.STATE_RINGING).when(secondCall).getState(); + mBluetoothInCallService.onCallAdded(baseCall); mBluetoothInCallService.onCallAdded(firstCall); mBluetoothInCallService.onCallAdded(secondCall); - when(baseCall.getHandle()).thenReturn(Uri.parse("tel:111-111")); - when(firstCall.getHandle()).thenReturn(Uri.parse("tel:222-222")); - when(secondCall.getHandle()).thenReturn(Uri.parse("tel:333-333")); - when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + + doReturn(Uri.parse("tel:111-111")).when(baseCall).getHandle(); + doReturn(Uri.parse("tel:222-222")).when(firstCall).getHandle(); + doReturn(Uri.parse("tel:333-333")).when(secondCall).getHandle(); doReturn(baseCall).when(mMockCallInfo).getCallByCallId(null); doReturn(firstCall).when(mMockCallInfo).getCallByCallId(firstJoiningCallId); doReturn(secondCall).when(mMockCallInfo).getCallByCallId(secondJoiningCallId); - callback.onJoinCalls(requestId, uuids); + mBluetoothInCallService.mBluetoothLeCallControlCallback.onJoinCalls(requestId, uuids); - verify(callControlProxy).requestResult(requestId, BluetoothLeCallControl.RESULT_SUCCESS); - verify(firstCall, times(1)).conference(any(BluetoothCall.class)); + verify(mLeCallControl).requestResult(requestId, BluetoothLeCallControl.RESULT_SUCCESS); + verify(firstCall).conference(any(BluetoothCall.class)); } private void addCallCapability(BluetoothCall call, int capability) { - when(call.can(capability)).thenReturn(true); - } - - private void removeCallCapability(BluetoothCall call, int capability) { - when(call.can(capability)).thenReturn(false); + doReturn(true).when(call).can(eq(capability)); } private BluetoothCall createActiveCall(UUID uuid) { BluetoothCall call = getMockCall(uuid); - when(mMockCallInfo.getActiveCall()).thenReturn(call); + doReturn(call).when(mMockCallInfo).getActiveCall(); return call; } private BluetoothCall createRingingCall(UUID uuid) { BluetoothCall call = getMockCall(uuid); - Log.i("BluetoothInCallService", "asdf creaete " + Integer.toString(call.hashCode())); - when(mMockCallInfo.getRingingOrSimulatedRingingCall()).thenReturn(call); + doReturn(call).when(mMockCallInfo).getRingingOrSimulatedRingingCall(); return call; } private BluetoothCall createHeldCall(UUID uuid) { BluetoothCall call = getMockCall(uuid); - when(mMockCallInfo.getHeldCall()).thenReturn(call); + doReturn(call).when(mMockCallInfo).getHeldCall(); return call; } private BluetoothCall createOutgoingCall(UUID uuid) { BluetoothCall call = getMockCall(uuid); - when(mMockCallInfo.getOutgoingCall()).thenReturn(call); + doReturn(call).when(mMockCallInfo).getOutgoingCall(); return call; } private BluetoothCall createDisconnectedCall(UUID uuid) { BluetoothCall call = getMockCall(uuid); - when(mMockCallInfo.getCallByState(Call.STATE_DISCONNECTED)).thenReturn(call); + doReturn(call).when(mMockCallInfo).getCallByState(Call.STATE_DISCONNECTED); return call; } private BluetoothCall createForegroundCall(UUID uuid) { BluetoothCall call = getMockCall(uuid); - when(mMockCallInfo.getForegroundCall()).thenReturn(call); + doReturn(call).when(mMockCallInfo).getForegroundCall(); return call; } @@ -2086,7 +1916,7 @@ public class BluetoothInCallServiceTest { private BluetoothCall getMockCall(UUID uuid) { BluetoothCall call = mock(com.android.bluetooth.telephony.BluetoothCall.class); Integer integerUuid = uuid.hashCode(); - when(call.getId()).thenReturn(integerUuid); + doReturn(integerUuid).when(call).getId(); return call; } } -- GitLab From e46715ffdc5d873aaf867268a51138d5dff96446 Mon Sep 17 00:00:00 2001 From: William Escande Date: Wed, 12 Jun 2024 16:43:39 -0700 Subject: [PATCH 0085/1446] InCallService: Close profile on the same adapter Test: atest BluetoothInstrumentationTests:BluetoothInCallServiceTest Flag: Exempt refactor Bug: 330247213 Change-Id: Ia42b26511769ed24f5d5cf2767f878417854f6ef --- .../bluetooth/hfp/BluetoothHeadsetProxy.java | 10 +++------- .../tbs/BluetoothLeCallControlProxy.java | 12 +++--------- .../telephony/BluetoothInCallService.java | 16 ++++++++++------ 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/android/app/src/com/android/bluetooth/hfp/BluetoothHeadsetProxy.java b/android/app/src/com/android/bluetooth/hfp/BluetoothHeadsetProxy.java index 650f159b486..fa46c294f29 100644 --- a/android/app/src/com/android/bluetooth/hfp/BluetoothHeadsetProxy.java +++ b/android/app/src/com/android/bluetooth/hfp/BluetoothHeadsetProxy.java @@ -16,11 +16,10 @@ package com.android.bluetooth.hfp; +import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; -import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; -import android.content.Context; import java.util.List; @@ -39,11 +38,8 @@ public class BluetoothHeadsetProxy { mBluetoothHeadset = headset; } - public void closeBluetoothHeadsetProxy(Context context) { - final BluetoothManager btManager = context.getSystemService(BluetoothManager.class); - if (btManager != null) { - btManager.getAdapter().closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset); - } + public void closeBluetoothHeadsetProxy(BluetoothAdapter adapter) { + adapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset); } public void clccResponse( diff --git a/android/app/src/com/android/bluetooth/tbs/BluetoothLeCallControlProxy.java b/android/app/src/com/android/bluetooth/tbs/BluetoothLeCallControlProxy.java index 8c4c3718b38..655da62bc35 100644 --- a/android/app/src/com/android/bluetooth/tbs/BluetoothLeCallControlProxy.java +++ b/android/app/src/com/android/bluetooth/tbs/BluetoothLeCallControlProxy.java @@ -17,11 +17,10 @@ package com.android.bluetooth.tbs; +import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothLeCall; import android.bluetooth.BluetoothLeCallControl; -import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; -import android.content.Context; import java.util.List; import java.util.UUID; @@ -52,13 +51,8 @@ public class BluetoothLeCallControlProxy { mBluetoothLeCallControl = tbs; } - public void closeBluetoothLeCallControlProxy(Context context) { - final BluetoothManager btManager = context.getSystemService(BluetoothManager.class); - if (btManager != null) { - btManager - .getAdapter() - .closeProfileProxy(BluetoothProfile.LE_CALL_CONTROL, mBluetoothLeCallControl); - } + public void closeBluetoothLeCallControlProxy(BluetoothAdapter adapter) { + adapter.closeProfileProxy(BluetoothProfile.LE_CALL_CONTROL, mBluetoothLeCallControl); } public boolean registerBearer( diff --git a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java index dbeee8cf818..5f878f59207 100644 --- a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java +++ b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java @@ -16,12 +16,15 @@ package com.android.bluetooth.telephony; +import static java.util.Objects.requireNonNull; + import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothLeCall; import android.bluetooth.BluetoothLeCallControl; +import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothProfile; import android.content.BroadcastReceiver; import android.content.Context; @@ -143,6 +146,8 @@ public class BluetoothInCallService extends InCallService { private int mMaxNumberOfCalls = 0; + private BluetoothAdapter mAdapter = null; + /** * Listens to connections and disconnections of bluetooth headsets. We need to save the current * bluetooth headset so that we know where to send BluetoothCall updates. @@ -735,10 +740,9 @@ public class BluetoothInCallService extends InCallService { public void onCreate() { Log.d(TAG, "onCreate"); super.onCreate(); - BluetoothAdapter.getDefaultAdapter() - .getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET); - BluetoothAdapter.getDefaultAdapter() - .getProfileProxy(this, mProfileListener, BluetoothProfile.LE_CALL_CONTROL); + mAdapter = requireNonNull(getSystemService(BluetoothManager.class)).getAdapter(); + mAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET); + mAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.LE_CALL_CONTROL); mBluetoothAdapterReceiver = new BluetoothAdapterReceiver(); IntentFilter intentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); @@ -768,12 +772,12 @@ public class BluetoothInCallService extends InCallService { mBluetoothAdapterReceiver = null; } if (mBluetoothHeadset != null) { - mBluetoothHeadset.closeBluetoothHeadsetProxy(this); + mBluetoothHeadset.closeBluetoothHeadsetProxy(mAdapter); mBluetoothHeadset = null; } if (mBluetoothLeCallControl != null) { mBluetoothLeCallControl.unregisterBearer(); - mBluetoothLeCallControl.closeBluetoothLeCallControlProxy(this); + mBluetoothLeCallControl.closeBluetoothLeCallControlProxy(mAdapter); } mProfileListener = null; sInstance = null; -- GitLab From bdca28852afa906eb1308eb27bff01786f9658ff Mon Sep 17 00:00:00 2001 From: William Escande Date: Wed, 12 Jun 2024 17:11:13 -0700 Subject: [PATCH 0086/1446] InCallService: profile listener is final Having a non-final potentially nullable listener is not recommended as this would lead to silent failure in the registration Bug: 330247213 Test: atest BluetoothInstrumentationTests:BluetoothInCallServiceTests Flag: Exempt refactor Change-Id: I175affe19378c4c85dabf3d4218e31d20eacd2d9 --- .../bluetooth/telephony/BluetoothInCallService.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java index 5f878f59207..72119ebc9ae 100644 --- a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java +++ b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java @@ -148,12 +148,7 @@ public class BluetoothInCallService extends InCallService { private BluetoothAdapter mAdapter = null; - /** - * Listens to connections and disconnections of bluetooth headsets. We need to save the current - * bluetooth headset so that we know where to send BluetoothCall updates. - */ - @VisibleForTesting - public BluetoothProfile.ServiceListener mProfileListener = + private final BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() { @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { @@ -779,7 +774,6 @@ public class BluetoothInCallService extends InCallService { mBluetoothLeCallControl.unregisterBearer(); mBluetoothLeCallControl.closeBluetoothLeCallControlProxy(mAdapter); } - mProfileListener = null; sInstance = null; mCallbacks.clear(); mBluetoothCallHashMap.clear(); -- GitLab From 96c8d709fb223ce011b6d411114b668d9af0b144 Mon Sep 17 00:00:00 2001 From: William Escande Date: Wed, 12 Jun 2024 17:31:18 -0700 Subject: [PATCH 0087/1446] InCallService: getService during onCreate Since there is no guarantee for when onBind will be called, we cannot use it to initialize critical systemService Bug: 330247213 Fix: 330247213 Test: atest BluetoothInstrumentationTests:BluetoothInCallServiceTests Test: atest BluetoothInstrumentationTests:CallInfoTest Flag: Exempt refactor Change-Id: I29459364d9425fef6b8b7ece8b5ff6a072f23bc3 --- .../telephony/BluetoothInCallService.java | 14 +++++--------- .../bluetooth/telephony/CallInfoTest.java | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java index 72119ebc9ae..157adfc2511 100644 --- a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java +++ b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java @@ -122,9 +122,8 @@ public class BluetoothInCallService extends InCallService { @VisibleForTesting BluetoothLeCallControlProxy mBluetoothLeCallControl; private ExecutorService mExecutor; - @VisibleForTesting public TelephonyManager mTelephonyManager; - - @VisibleForTesting public TelecomManager mTelecomManager; + private TelephonyManager mTelephonyManager; + private TelecomManager mTelecomManager; @VisibleForTesting public final HashMap mCallbacks = new HashMap<>(); @@ -334,10 +333,7 @@ public class BluetoothInCallService extends InCallService { @Override public IBinder onBind(Intent intent) { Log.i(TAG, "onBind. Intent: " + intent); - IBinder binder = super.onBind(intent); - mTelephonyManager = getSystemService(TelephonyManager.class); - mTelecomManager = getSystemService(TelecomManager.class); - return binder; + return super.onBind(intent); } @Override @@ -367,8 +363,6 @@ public class BluetoothInCallService extends InCallService { mBluetoothHeadset = headset; mBluetoothLeCallControl = leCallControl; attachBaseContext(context); - mTelephonyManager = getSystemService(TelephonyManager.class); - mTelecomManager = getSystemService(TelecomManager.class); } public static BluetoothInCallService getInstance() { @@ -736,6 +730,8 @@ public class BluetoothInCallService extends InCallService { Log.d(TAG, "onCreate"); super.onCreate(); mAdapter = requireNonNull(getSystemService(BluetoothManager.class)).getAdapter(); + mTelephonyManager = getSystemService(TelephonyManager.class); + mTelecomManager = getSystemService(TelecomManager.class); mAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET); mAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.LE_CALL_CONTROL); mBluetoothAdapterReceiver = new BluetoothAdapterReceiver(); diff --git a/android/app/tests/unit/src/com/android/bluetooth/telephony/CallInfoTest.java b/android/app/tests/unit/src/com/android/bluetooth/telephony/CallInfoTest.java index a1796a4d127..6cfa5b36873 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/telephony/CallInfoTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/telephony/CallInfoTest.java @@ -24,6 +24,8 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.ComponentName; +import android.content.Context; +import android.content.ContextWrapper; import android.net.Uri; import android.os.Process; import android.telecom.Call; @@ -31,15 +33,17 @@ import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; +import androidx.test.core.app.ApplicationProvider; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.bluetooth.TestUtils; + import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -57,15 +61,21 @@ public class CallInfoTest { @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - @Mock private TelecomManager mMockTelecomManager; + private TelecomManager mMockTelecomManager; private BluetoothInCallService mBluetoothInCallService; private BluetoothInCallService.CallInfo mMockCallInfo; @Before public void setUp() throws Exception { + Context spiedContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext())); + mMockTelecomManager = + TestUtils.mockGetSystemService( + spiedContext, Context.TELECOM_SERVICE, TelecomManager.class); + + mBluetoothInCallService = new BluetoothInCallService(spiedContext, null, null, null); + mBluetoothInCallService.onCreate(); - mBluetoothInCallService = new BluetoothInCallService(); mMockCallInfo = spy(mBluetoothInCallService.new CallInfo()); } @@ -273,7 +283,6 @@ public class CallInfoTest { PhoneAccount fakePhoneAccount = makeQuickAccount(testId, TEST_ACCOUNT_INDEX); when(mMockTelecomManager.getPhoneAccount(testHandle)).thenReturn(fakePhoneAccount); - mBluetoothInCallService.mTelecomManager = mMockTelecomManager; assertThat(mMockCallInfo.getBestPhoneAccount()).isEqualTo(fakePhoneAccount); } -- GitLab From 9d9075c8620a18f5766a8907ca61d351c0baf2e8 Mon Sep 17 00:00:00 2001 From: William Escande Date: Wed, 12 Jun 2024 17:32:57 -0700 Subject: [PATCH 0088/1446] InCallService: Telephony and Telecom cannot be null Acknowledge that the BluetoothInCallService cannot be created if there is no TelephonyManager or TelecomManager + cleanup dead code related to variable not being nullable anymore Bug: 330247213 Test: atest BluetoothInstrumentationTests:BluetoothInCallServiceTest Flag: Exempt refactor Change-Id: Ic576c05ff8cbb1dacce56b6ed24e710fd0e9c4ef --- .../telephony/BluetoothInCallService.java | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java index 157adfc2511..3928e3c6771 100644 --- a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java +++ b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java @@ -514,11 +514,7 @@ public class BluetoothInCallService extends InCallService { } } if (TextUtils.isEmpty(address)) { - if (mTelephonyManager == null) { - address = null; - } else { - address = mTelephonyManager.getLine1Number(); - } + address = mTelephonyManager.getLine1Number(); if (address == null) address = ""; } return address; @@ -730,8 +726,8 @@ public class BluetoothInCallService extends InCallService { Log.d(TAG, "onCreate"); super.onCreate(); mAdapter = requireNonNull(getSystemService(BluetoothManager.class)).getAdapter(); - mTelephonyManager = getSystemService(TelephonyManager.class); - mTelecomManager = getSystemService(TelecomManager.class); + mTelephonyManager = requireNonNull(getSystemService(TelephonyManager.class)); + mTelecomManager = requireNonNull(getSystemService(TelecomManager.class)); mAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET); mAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.LE_CALL_CONTROL); mBluetoothAdapterReceiver = new BluetoothAdapterReceiver(); @@ -828,10 +824,6 @@ public class BluetoothInCallService extends InCallService { Log.w(TAG, "call id: " + bluetoothCall.getId() + " handle is null"); continue; } - if (mTelephonyManager == null) { - Log.w(TAG, "mTelephonyManager is null"); - continue; - } boolean isSame = PhoneNumberUtils.areSamePhoneNumber( bluetoothCall.getHandle().toString(), @@ -1533,10 +1525,6 @@ public class BluetoothInCallService extends InCallService { if (account == null) { // Second, Try to get the label for the default Phone Account. - if (mTelecomManager == null) { - Log.w(TAG, "mTelecomManager is null"); - return null; - } List handles = mTelecomManager.getPhoneAccountsSupportingScheme(PhoneAccount.SCHEME_TEL); while (handles.iterator().hasNext()) { @@ -1569,7 +1557,7 @@ public class BluetoothInCallService extends InCallService { public void setBluetoothLeCallControl(BluetoothLeCallControlProxy bluetoothTbs) { mBluetoothLeCallControl = bluetoothTbs; - if ((mBluetoothLeCallControl) != null && (mTelecomManager != null)) { + if ((mBluetoothLeCallControl) != null) { mBluetoothLeCallControl.registerBearer( TAG, new ArrayList(Arrays.asList("tel")), -- GitLab From 599036181d0299739cd48f92c8604ad297258400 Mon Sep 17 00:00:00 2001 From: William Escande Date: Wed, 19 Jun 2024 19:32:45 -0700 Subject: [PATCH 0089/1446] InCallService: Stop hiding code in setter When setting the headset or LeCall, it is confusing that the setter is doing more than setting it. By inlining the method, we remove this abstraction Bug: 330247213 Fix: 330247213 Test: atest BluetoothInstrumentationTests:BluetoothInCallServiceTests Flag: Exempt refactor Change-Id: Ice096f0c02222b9b88d60fceeeea23d165d95d52 --- .../telephony/BluetoothInCallService.java | 43 ++++++------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java index 3928e3c6771..97946651fc5 100644 --- a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java +++ b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java @@ -56,7 +56,6 @@ import com.android.bluetooth.tbs.BluetoothLeCallControlProxy; import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashSet; @@ -153,13 +152,20 @@ public class BluetoothInCallService extends InCallService { public void onServiceConnected(int profile, BluetoothProfile proxy) { synchronized (LOCK) { if (profile == BluetoothProfile.HEADSET) { - setBluetoothHeadset( - new BluetoothHeadsetProxy((BluetoothHeadset) proxy)); + mBluetoothHeadset = new BluetoothHeadsetProxy((BluetoothHeadset) proxy); updateHeadsetWithCallState(true /* force */); } else { - setBluetoothLeCallControl( - new BluetoothLeCallControlProxy( - (BluetoothLeCallControl) proxy)); + mBluetoothLeCallControl = + new BluetoothLeCallControlProxy((BluetoothLeCallControl) proxy); + + mBluetoothLeCallControl.registerBearer( + TAG, + List.of("tel"), + BluetoothLeCallControl.CAPABILITY_HOLD_CALL, + getNetworkOperator(), + getBearerTechnology(), + mExecutor, + mBluetoothLeCallControlCallback); sendTbsCurrentCallsList(); } } @@ -169,9 +175,9 @@ public class BluetoothInCallService extends InCallService { public void onServiceDisconnected(int profile) { synchronized (LOCK) { if (profile == BluetoothProfile.HEADSET) { - setBluetoothHeadset(null); + mBluetoothHeadset = null; } else { - setBluetoothLeCallControl(null); + mBluetoothLeCallControl = null; } } } @@ -1377,11 +1383,6 @@ public class BluetoothInCallService extends InCallService { return mCallbacks.get(call.getId()); } - @VisibleForTesting - public void setBluetoothHeadset(BluetoothHeadsetProxy bluetoothHeadset) { - mBluetoothHeadset = bluetoothHeadset; - } - @VisibleForTesting public BluetoothCall getBluetoothCallById(Integer id) { if (mBluetoothCallHashMap.containsKey(id)) { @@ -1553,22 +1554,6 @@ public class BluetoothInCallService extends InCallService { } } - @VisibleForTesting - public void setBluetoothLeCallControl(BluetoothLeCallControlProxy bluetoothTbs) { - mBluetoothLeCallControl = bluetoothTbs; - - if ((mBluetoothLeCallControl) != null) { - mBluetoothLeCallControl.registerBearer( - TAG, - new ArrayList(Arrays.asList("tel")), - BluetoothLeCallControl.CAPABILITY_HOLD_CALL, - getNetworkOperator(), - getBearerTechnology(), - mExecutor, - mBluetoothLeCallControlCallback); - } - } - private Integer getTbsCallState(BluetoothCall call) { switch (call.getState()) { case Call.STATE_ACTIVE: -- GitLab From 9979418fd89a7074d2feac54f8a257eec49802d2 Mon Sep 17 00:00:00 2001 From: Hyundo Moon Date: Tue, 18 Jun 2024 14:50:31 +0900 Subject: [PATCH 0090/1446] Opt out from edge-to-edge in OppTransferHistory Bug: 347139185 Test: m -j; Test: Opened the activity and checked that the issue is gone. Flag: EXEMPT, internal-only change Ignore-AOSP-First: The edge-to-edge is only added in internal main. Change-Id: I52bd925b0ef8fe42633133d2005ad3a1b3ba871a --- android/app/res/values-v35/styles.xml | 27 +++++++++++++++++++ android/app/res/values/styles.xml | 7 ++++- .../opp/BluetoothOppTransferHistory.java | 4 +++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 android/app/res/values-v35/styles.xml diff --git a/android/app/res/values-v35/styles.xml b/android/app/res/values-v35/styles.xml new file mode 100644 index 00000000000..5785e5500c7 --- /dev/null +++ b/android/app/res/values-v35/styles.xml @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/android/app/res/values/styles.xml b/android/app/res/values/styles.xml index ea9469599e1..2d8e5fd2415 100644 --- a/android/app/res/values/styles.xml +++ b/android/app/res/values/styles.xml @@ -45,6 +45,11 @@ ?android:attr/textColorPrimary - + + diff --git a/android/app/res/values/styles.xml b/android/app/res/values/styles.xml index ea9469599e1..2d8e5fd2415 100644 --- a/android/app/res/values/styles.xml +++ b/android/app/res/values/styles.xml @@ -45,6 +45,11 @@ ?android:attr/textColorPrimary -