diff --git a/TEST_MAPPING b/TEST_MAPPING index 5f6e3786141962e905c86dfb9f383d726ca01bfc..8b050569be7931e19160e644db7f3fabc7056c6f 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -76,6 +76,10 @@ { "name" : "net_test_types", "host" : true + }, + { + "name" : "net_test_btif_rc", + "host" : true } ] } diff --git a/system/btif/Android.bp b/system/btif/Android.bp index 26a30bffcfd69919be5289a84f2955bcea3f0ae6..f9370ab3fe6d655f1094e67554dd3f6602432db5 100644 --- a/system/btif/Android.bp +++ b/system/btif/Android.bp @@ -208,3 +208,36 @@ cc_test { ], cflags: ["-DBUILDCFG"], } + +// btif rc unit tests for target +// ======================================================== +cc_test { + name: "net_test_btif_rc", + defaults: ["fluoride_defaults"], + test_suites: ["device-tests"], + host_supported: true, + include_dirs: btifCommonIncludes, + srcs: [ + "test/btif_rc_test.cc", + ], + header_libs: ["libbluetooth_headers"], + shared_libs: [ + "libcrypto", + "libcutils", + "liblog", + "libprotobuf-cpp-lite", + ], + static_libs: [ + "libbluetooth-types", + "libbt-common", + "libbt-protos-lite", + "libosi", + "libosi-AllocationTestHarness", + ], + cflags: ["-DBUILDCFG"], + sanitize: { + address: true, + cfi: true, + misc_undefined: ["bounds"], + }, +} diff --git a/system/btif/src/btif_rc.cc b/system/btif/src/btif_rc.cc index 571967e04cd312488fd2903a7ee567ccedd64ad9..575d83e372ac425ca3114939075be64a2ec23a0c 100644 --- a/system/btif/src/btif_rc.cc +++ b/system/btif/src/btif_rc.cc @@ -1836,6 +1836,12 @@ static bt_status_t get_element_attr_rsp(const RawAddress& bd_addr, BTIF_TRACE_DEBUG("%s", __func__); CHECK_RC_CONNECTED(p_dev); + if (num_attr > BTRC_MAX_ELEM_ATTR_SIZE) { + LOG(WARNING) << __func__ + << " Exceeded number attributes:" << static_cast<int>(num_attr) + << " max:" << BTRC_MAX_ELEM_ATTR_SIZE; + num_attr = BTRC_MAX_ELEM_ATTR_SIZE; + } memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr); if (num_attr == 0) { @@ -1844,7 +1850,8 @@ static bt_status_t get_element_attr_rsp(const RawAddress& bd_addr, for (i = 0; i < num_attr; i++) { element_attrs[i].attr_id = p_attrs[i].attr_id; element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8; - element_attrs[i].name.str_len = (uint16_t)strlen((char*)p_attrs[i].text); + element_attrs[i].name.str_len = + (uint16_t)strnlen((char*)p_attrs[i].text, BTRC_MAX_ATTR_STR_LEN); element_attrs[i].name.p_str = p_attrs[i].text; BTIF_TRACE_DEBUG( "%s: attr_id: 0x%x, charset_id: 0x%x, str_len: %d, str: %s", __func__, diff --git a/system/btif/test/btif_rc_test.cc b/system/btif/test/btif_rc_test.cc new file mode 100644 index 0000000000000000000000000000000000000000..6271881c917f7df60f85f63b35785cb49a49caf2 --- /dev/null +++ b/system/btif/test/btif_rc_test.cc @@ -0,0 +1,131 @@ +/* + * 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. + */ + +#include <base/logging.h> +#include <gtest/gtest.h> +#include <stdio.h> +#include <cstdint> + +#include "bta/include/bta_av_api.h" +#include "btif/include/btif_common.h" +#include "device/include/interop.h" +#include "include/hardware/bt_rc.h" +#include "osi/test/AllocationTestHarness.h" +#include "stack/include/btm_api_types.h" +#include "types/raw_address.h" +#undef LOG_TAG +#include "btif/src/btif_rc.cc" + +extern void allocation_tracker_uninit(void); + +namespace { +int AVRC_BldResponse_ = 0; +} // namespace + +uint8_t appl_trace_level = BT_TRACE_LEVEL_WARNING; +uint8_t btif_trace_level = BT_TRACE_LEVEL_WARNING; + +tAVRC_STS AVRC_BldCommand(tAVRC_COMMAND* p_cmd, BT_HDR** pp_pkt) { return 0; } +tAVRC_STS AVRC_BldResponse(uint8_t handle, tAVRC_RESPONSE* p_rsp, + BT_HDR** pp_pkt) { + AVRC_BldResponse_++; + return 0; +} +tAVRC_STS AVRC_Ctrl_ParsCommand(tAVRC_MSG* p_msg, tAVRC_COMMAND* p_result) { + return 0; +} +tAVRC_STS AVRC_Ctrl_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result, + uint8_t* p_buf, uint16_t* buf_len) { + return 0; +} +tAVRC_STS AVRC_ParsCommand(tAVRC_MSG* p_msg, tAVRC_COMMAND* p_result, + uint8_t* p_buf, uint16_t buf_len) { + return 0; +} +tAVRC_STS AVRC_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result, + UNUSED_ATTR uint8_t* p_buf, + UNUSED_ATTR uint16_t buf_len) { + return 0; +} +void BTA_AvCloseRc(uint8_t rc_handle) {} +void BTA_AvMetaCmd(uint8_t rc_handle, uint8_t label, tBTA_AV_CMD cmd_code, + BT_HDR* p_pkt) {} +void BTA_AvMetaRsp(uint8_t rc_handle, uint8_t label, tBTA_AV_CODE rsp_code, + BT_HDR* p_pkt) {} +void BTA_AvRemoteCmd(uint8_t rc_handle, uint8_t label, tBTA_AV_RC rc_id, + tBTA_AV_STATE key_state) {} +void BTA_AvRemoteVendorUniqueCmd(uint8_t rc_handle, uint8_t label, + tBTA_AV_STATE key_state, uint8_t* p_msg, + uint8_t buf_len) {} +void BTA_AvVendorCmd(uint8_t rc_handle, uint8_t label, tBTA_AV_CODE cmd_code, + uint8_t* p_data, uint16_t len) {} +void BTA_AvVendorRsp(uint8_t rc_handle, uint8_t label, tBTA_AV_CODE rsp_code, + uint8_t* p_data, uint16_t len, uint32_t company_id) {} +void btif_av_clear_remote_suspend_flag(void) {} +bool btif_av_is_connected(void) { return false; } +bool btif_av_is_sink_enabled(void) { return false; } +RawAddress btif_av_sink_active_peer(void) { return RawAddress(); } +RawAddress btif_av_source_active_peer(void) { return RawAddress(); } +bool btif_av_stream_started_ready(void) { return false; } +bt_status_t btif_transfer_context(tBTIF_CBACK* p_cback, uint16_t event, + char* p_params, int param_len, + tBTIF_COPY_CBACK* p_copy_cback) { + return BT_STATUS_SUCCESS; +} +const char* dump_rc_event(uint8_t event) { return nullptr; } +const char* dump_rc_notification_event_id(uint8_t event_id) { return nullptr; } +const char* dump_rc_pdu(uint8_t pdu) { return nullptr; } +bt_status_t do_in_jni_thread(const base::Location& from_here, + base::OnceClosure task) { + return BT_STATUS_SUCCESS; +} +base::MessageLoop* get_main_message_loop() { return nullptr; } +bool interop_match_addr(const interop_feature_t feature, + const RawAddress* addr) { + return false; +} +void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {} + +/** + * Test class to test selected functionality in hci/src/hci_layer.cc + */ +class BtifRcTest : public AllocationTestHarness { + protected: + void SetUp() override { + AllocationTestHarness::SetUp(); + // Disable our allocation tracker to allow ASAN full range + allocation_tracker_uninit(); + } + + void TearDown() override { AllocationTestHarness::TearDown(); } +}; + +TEST_F(BtifRcTest, get_element_attr_rsp) { + RawAddress bd_addr; + + btif_rc_cb.rc_multi_cb[0].rc_addr = bd_addr; + btif_rc_cb.rc_multi_cb[0].rc_connected = true; + btif_rc_cb.rc_multi_cb[0] + .rc_pdu_info[IDX_GET_ELEMENT_ATTR_RSP] + .is_rsp_pending = true; + btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED; + + btrc_element_attr_val_t p_attrs[BTRC_MAX_ELEM_ATTR_SIZE]; + uint8_t num_attr = BTRC_MAX_ELEM_ATTR_SIZE + 1; + + CHECK(get_element_attr_rsp(bd_addr, num_attr, p_attrs) == BT_STATUS_SUCCESS); + CHECK(AVRC_BldResponse_ == 1); +}