1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #undef LOG_TAG // Undefine the LOG_TAG by this compilation unit
18 #include "btif/src/btif_rc.cc"
19
20 #include <bluetooth/log.h>
21 #include <gtest/gtest.h>
22
23 #include <cstdint>
24 #include <future>
25
26 #include "bta/include/bta_av_api.h"
27 #include "btif/avrcp/avrcp_service.h"
28 #include "btif/include/btif_common.h"
29 #include "common/message_loop_thread.h"
30 #include "device/include/interop.h"
31 #include "include/hardware/bt_rc.h"
32 #include "stack/include/main_thread.h"
33 #include "test/common/mock_functions.h"
34 #include "test/mock/mock_osi_alarm.h"
35 #include "test/mock/mock_osi_allocator.h"
36 #include "test/mock/mock_osi_list.h"
37 #include "types/raw_address.h"
38
39 namespace bluetooth {
40 namespace avrcp {
41 int VolChanged = 0;
42 AvrcpService* AvrcpService::instance_ = nullptr;
43
SendMediaUpdate(bool,bool,bool)44 void AvrcpService::SendMediaUpdate(bool /*track_changed*/, bool /*play_state*/, bool /*queue*/) {}
SendFolderUpdate(bool,bool,bool)45 void AvrcpService::SendFolderUpdate(bool /*available_players*/, bool /*addressed_players*/,
46 bool /*uids*/) {}
SendPlayerSettingsChanged(std::vector<PlayerAttribute>,std::vector<uint8_t>)47 void AvrcpService::SendPlayerSettingsChanged(std::vector<PlayerAttribute> /*attributes*/,
48 std::vector<uint8_t> /*values*/) {}
Init(MediaInterface *,VolumeInterface *,PlayerSettingsInterface *)49 void AvrcpService::ServiceInterfaceImpl::Init(
50 MediaInterface* /*media_interface*/, VolumeInterface* /*volume_interface*/,
51 PlayerSettingsInterface* /*player_settings_interface*/) {}
RegisterBipServer(int)52 void AvrcpService::ServiceInterfaceImpl::RegisterBipServer(int /*psm*/) {}
UnregisterBipServer()53 void AvrcpService::ServiceInterfaceImpl::UnregisterBipServer() {}
ConnectDevice(const RawAddress &)54 bool AvrcpService::ServiceInterfaceImpl::ConnectDevice(const RawAddress& /*bdaddr*/) {
55 return true;
56 }
DisconnectDevice(const RawAddress &)57 bool AvrcpService::ServiceInterfaceImpl::DisconnectDevice(const RawAddress& /*bdaddr*/) {
58 return true;
59 }
SetBipClientStatus(const RawAddress &,bool)60 void AvrcpService::ServiceInterfaceImpl::SetBipClientStatus(const RawAddress& /*bdaddr*/,
61 bool /*connected*/) {}
Cleanup()62 bool AvrcpService::ServiceInterfaceImpl::Cleanup() { return true; }
63
Get()64 AvrcpService* AvrcpService::Get() {
65 EXPECT_EQ(instance_, nullptr);
66 instance_ = new AvrcpService();
67 return instance_;
68 }
69
RegisterVolChanged(const RawAddress &)70 void AvrcpService::RegisterVolChanged(const RawAddress& /*bdaddr*/) { VolChanged++; }
71 } // namespace avrcp
72 } // namespace bluetooth
73
74 namespace {
75 const RawAddress kDeviceAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
76 const uint8_t kRcHandle = 123;
77 } // namespace
78
btif_av_clear_remote_suspend_flag(const A2dpType)79 void btif_av_clear_remote_suspend_flag(const A2dpType /*local_a2dp_type*/) {}
btif_av_is_connected(const A2dpType)80 bool btif_av_is_connected(const A2dpType /*local_a2dp_type*/) { return true; }
btif_av_is_sink_enabled(void)81 bool btif_av_is_sink_enabled(void) { return true; }
btif_av_sink_active_peer(void)82 RawAddress btif_av_sink_active_peer(void) { return RawAddress(); }
btif_av_source_active_peer(void)83 RawAddress btif_av_source_active_peer(void) { return RawAddress(); }
btif_av_stream_started_ready(const A2dpType)84 bool btif_av_stream_started_ready(const A2dpType /*local_a2dp_type*/) { return false; }
btif_transfer_context(tBTIF_CBACK *,uint16_t,char *,int,tBTIF_COPY_CBACK *)85 bt_status_t btif_transfer_context(tBTIF_CBACK* /*p_cback*/, uint16_t /*event*/, char* /*p_params*/,
86 int /*param_len*/, tBTIF_COPY_CBACK* /*p_copy_cback*/) {
87 return BT_STATUS_SUCCESS;
88 }
btif_av_src_sink_coexist_enabled()89 bool btif_av_src_sink_coexist_enabled() { return true; }
btif_av_is_connected_addr(const RawAddress &,const A2dpType)90 bool btif_av_is_connected_addr(const RawAddress& /*peer_address*/,
91 const A2dpType /*local_a2dp_type*/) {
92 return true;
93 }
btif_av_peer_is_connected_sink(const RawAddress &)94 bool btif_av_peer_is_connected_sink(const RawAddress& /*peer_address*/) { return false; }
btif_av_peer_is_connected_source(const RawAddress &)95 bool btif_av_peer_is_connected_source(const RawAddress& /*peer_address*/) { return true; }
btif_av_peer_is_sink(const RawAddress &)96 bool btif_av_peer_is_sink(const RawAddress& /*peer_address*/) { return false; }
btif_av_peer_is_source(const RawAddress &)97 bool btif_av_peer_is_source(const RawAddress& /*peer_address*/) { return true; }
btif_av_both_enable(void)98 bool btif_av_both_enable(void) { return true; }
99
100 static bluetooth::common::MessageLoopThread jni_thread("bt_jni_thread");
do_in_jni_thread(base::OnceClosure task)101 bt_status_t do_in_jni_thread(base::OnceClosure task) {
102 if (!jni_thread.DoInThread(std::move(task))) {
103 log::error("Post task to task runner failed!");
104 return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
105 }
106 return BT_STATUS_SUCCESS;
107 }
get_main_thread()108 bluetooth::common::MessageLoopThread* get_main_thread() { return nullptr; }
interop_match_addr(const interop_feature_t,const RawAddress *)109 bool interop_match_addr(const interop_feature_t /*feature*/, const RawAddress* /*addr*/) {
110 return false;
111 }
112
113 /**
114 * Test class to test selected functionality in hci/src/hci_layer.cc
115 */
116 class BtifRcTest : public ::testing::Test {
117 protected:
SetUp()118 void SetUp() override { reset_mock_function_count_map(); }
TearDown()119 void TearDown() override {}
120 };
121
TEST_F(BtifRcTest,btif_rc_get_addr_by_handle)122 TEST_F(BtifRcTest, btif_rc_get_addr_by_handle) {
123 RawAddress bd_addr;
124
125 btif_rc_cb.rc_multi_cb[0].rc_addr = kDeviceAddress;
126 btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
127 btif_rc_cb.rc_multi_cb[0].rc_handle = 0;
128
129 btif_rc_get_addr_by_handle(0, bd_addr);
130 ASSERT_EQ(kDeviceAddress, bd_addr);
131 }
132
133 static btrc_ctrl_callbacks_t default_btrc_ctrl_callbacks = {
134 .size = sizeof(btrc_ctrl_callbacks_t),
135 .passthrough_rsp_cb = [](const RawAddress& /* bd_addr */, int /* id */,
__anon97df6eb30202() 136 int /* key_state */) { FAIL(); },
__anon97df6eb30302() 137 .groupnavigation_rsp_cb = [](int /* id */, int /* key_state */) { FAIL(); },
138 .connection_state_cb = [](bool /* rc_connect */, bool /* bt_connect */,
__anon97df6eb30402() 139 const RawAddress& /* bd_addr */) { FAIL(); },
__anon97df6eb30502() 140 .getrcfeatures_cb = [](const RawAddress& /* bd_addr */, int /* features */) { FAIL(); },
141 .setplayerappsetting_rsp_cb = [](const RawAddress& /* bd_addr */,
__anon97df6eb30602() 142 uint8_t /* accepted */) { FAIL(); },
143 .playerapplicationsetting_cb = [](const RawAddress& /* bd_addr */, uint8_t /* num_attr */,
144 btrc_player_app_attr_t* /* app_attrs */,
145 uint8_t /* num_ext_attr */,
__anon97df6eb30702() 146 btrc_player_app_ext_attr_t* /* ext_attrs */) { FAIL(); },
147 .playerapplicationsetting_changed_cb =
__anon97df6eb30802() 148 [](const RawAddress& /* bd_addr */, const btrc_player_settings_t& /* vals */) {
149 FAIL();
150 },
151 .setabsvol_cmd_cb = [](const RawAddress& /* bd_addr */, uint8_t /* abs_vol */,
__anon97df6eb30902() 152 uint8_t /* label */) { FAIL(); },
153 .registernotification_absvol_cb = [](const RawAddress& /* bd_addr */,
__anon97df6eb30a02() 154 uint8_t /* label */) { FAIL(); },
155 .track_changed_cb = [](const RawAddress& /* bd_addr */, uint8_t /* num_attr */,
__anon97df6eb30b02() 156 btrc_element_attr_val_t* /* p_attrs */) { FAIL(); },
157 .play_position_changed_cb = [](const RawAddress& /* bd_addr */, uint32_t /* song_len */,
__anon97df6eb30c02() 158 uint32_t /* song_pos */) { FAIL(); },
159 .play_status_changed_cb = [](const RawAddress& /* bd_addr */,
__anon97df6eb30d02() 160 btrc_play_status_t /* play_status */) { FAIL(); },
161 .get_folder_items_cb = [](const RawAddress& /* bd_addr */, btrc_status_t /* status */,
162 const btrc_folder_items_t* /* folder_items */,
__anon97df6eb30e02() 163 uint8_t /* count */) { FAIL(); },
164 .change_folder_path_cb = [](const RawAddress& /* bd_addr */,
__anon97df6eb30f02() 165 uint32_t /* count */) { FAIL(); },
166 .set_browsed_player_cb = [](const RawAddress& /* bd_addr */, uint8_t /* num_items */,
__anon97df6eb31002() 167 uint8_t /* depth */) { FAIL(); },
168 .set_addressed_player_cb = [](const RawAddress& /* bd_addr */,
__anon97df6eb31102() 169 uint8_t /* status */) { FAIL(); },
170 .addressed_player_changed_cb = [](const RawAddress& /* bd_addr */,
__anon97df6eb31202() 171 uint16_t /* id */) { FAIL(); },
__anon97df6eb31302() 172 .now_playing_contents_changed_cb = [](const RawAddress& /* bd_addr */) { FAIL(); },
__anon97df6eb31402() 173 .available_player_changed_cb = [](const RawAddress& /* bd_addr */) { FAIL(); },
174 .get_cover_art_psm_cb = [](const RawAddress& /* bd_addr */,
__anon97df6eb31502() 175 const uint16_t /* psm */) { FAIL(); },
176 };
177 static btrc_ctrl_callbacks_t btrc_ctrl_callbacks = default_btrc_ctrl_callbacks;
178
179 struct rc_connection_state_cb_t {
180 bool rc_state;
181 bool bt_state;
182 RawAddress raw_address;
183 };
184
185 struct rc_feature_cb_t {
186 int feature;
187 RawAddress raw_address;
188 };
189
190 static std::promise<rc_connection_state_cb_t> g_btrc_connection_state_promise;
191 static std::promise<rc_feature_cb_t> g_btrc_feature;
192
193 class BtifRcWithCallbacksTest : public BtifRcTest {
194 protected:
SetUp()195 void SetUp() override {
196 BtifRcTest::SetUp();
197 btrc_ctrl_callbacks = default_btrc_ctrl_callbacks;
198 init_ctrl(&btrc_ctrl_callbacks);
199 jni_thread.StartUp();
200 btrc_ctrl_callbacks.getrcfeatures_cb = [](const RawAddress& bd_addr, int features) {
201 rc_feature_cb_t rc_feature = {
202 .feature = features,
203 .raw_address = bd_addr,
204 };
205 g_btrc_feature.set_value(rc_feature);
206 };
207 }
208
TearDown()209 void TearDown() override {
210 jni_thread.ShutDown();
211 bt_rc_ctrl_callbacks->getrcfeatures_cb = [](const RawAddress& /*bd_addr*/, int /*features*/) {};
212 btrc_ctrl_callbacks = default_btrc_ctrl_callbacks;
213 BtifRcTest::TearDown();
214 }
215 };
216
TEST_F(BtifRcWithCallbacksTest,handle_rc_ctrl_features)217 TEST_F(BtifRcWithCallbacksTest, handle_rc_ctrl_features) {
218 g_btrc_feature = std::promise<rc_feature_cb_t>();
219 std::future<rc_feature_cb_t> future = g_btrc_feature.get_future();
220 btif_rc_device_cb_t p_dev;
221
222 p_dev.peer_tg_features =
223 (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_RCCT | BTA_AV_FEAT_METADATA |
224 BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_BROWSE | BTA_AV_FEAT_COVER_ARTWORK);
225 p_dev.rc_connected = true;
226
227 handle_rc_ctrl_features(&p_dev);
228 ASSERT_EQ(1, get_func_call_count("AVRC_BldCommand"));
229
230 ASSERT_EQ(std::future_status::ready, future.wait_for(std::chrono::seconds(2)));
231 auto res = future.get();
232 log::info("FEATURES:{}", res.feature);
233 ASSERT_EQ(res.feature, (BTRC_FEAT_ABSOLUTE_VOLUME | BTRC_FEAT_METADATA | BTRC_FEAT_BROWSE |
234 BTRC_FEAT_COVER_ARTWORK));
235 }
236
TEST_F(BtifRcTest,handle_track_change_notification_response)237 TEST_F(BtifRcTest, handle_track_change_notification_response) {
238 btif_rc_cb.rc_multi_cb[0].rc_connected = true;
239 btif_rc_cb.rc_multi_cb[0].br_connected = true;
240 btif_rc_cb.rc_multi_cb[0].rc_handle = kRcHandle;
241 btif_rc_cb.rc_multi_cb[0].rc_features = {};
242 btif_rc_cb.rc_multi_cb[0].rc_cover_art_psm = 0;
243 btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
244 btif_rc_cb.rc_multi_cb[0].rc_addr = kDeviceAddress;
245 btif_rc_cb.rc_multi_cb[0].rc_volume = 0;
246 btif_rc_cb.rc_multi_cb[0].rc_vol_label = 0;
247 btif_rc_cb.rc_multi_cb[0].rc_supported_event_list = nullptr;
248 btif_rc_cb.rc_multi_cb[0].rc_app_settings = {};
249 btif_rc_cb.rc_multi_cb[0].rc_play_status_timer = nullptr;
250 btif_rc_cb.rc_multi_cb[0].rc_features_processed = false;
251 btif_rc_cb.rc_multi_cb[0].rc_playing_uid = 0;
252 btif_rc_cb.rc_multi_cb[0].rc_procedure_complete = false;
253 btif_rc_cb.rc_multi_cb[0].peer_ct_features = {};
254 btif_rc_cb.rc_multi_cb[0].peer_tg_features = {};
255 btif_rc_cb.rc_multi_cb[0].launch_cmd_pending = 0;
256 ASSERT_TRUE(btif_rc_get_device_by_handle(kRcHandle));
257 tBTA_AV_META_MSG meta_msg = {
258 .rc_handle = kRcHandle,
259 .len = 0,
260 .label = 0,
261 .code = AVRC_RSP_CHANGED,
262 .company_id = 0,
263 .p_data = {},
264 .p_msg = nullptr,
265 };
266 tAVRC_NOTIF_RSP_PARAM param = {
267 .track = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
268 };
269 tAVRC_REG_NOTIF_RSP track_change = {
270 .pdu = 0,
271 .status = AVRC_STS_NO_ERROR,
272 .opcode = 0,
273 .event_id = AVRC_EVT_TRACK_CHANGE,
274 .param = param,
275 };
276 uint64_t now_playing_uid = 0x01;
277
278 handle_notification_response(&meta_msg, &track_change);
279 ASSERT_EQ(btif_rc_cb.rc_multi_cb[0].rc_playing_uid, now_playing_uid);
280 }
281
282 class BtifRcBrowseConnectionTest : public BtifRcTest {
283 protected:
SetUp()284 void SetUp() override {
285 BtifRcTest::SetUp();
286 init_ctrl(&btrc_ctrl_callbacks);
287 jni_thread.StartUp();
288 btrc_ctrl_callbacks.connection_state_cb = [](bool rc_state, bool bt_state,
289 const RawAddress& bd_addr) {
290 rc_connection_state_cb_t rc_connection_state = {
291 .rc_state = rc_state,
292 .bt_state = bt_state,
293 .raw_address = bd_addr,
294 };
295 g_btrc_connection_state_promise.set_value(rc_connection_state);
296 };
297 }
298
TearDown()299 void TearDown() override {
300 jni_thread.ShutDown();
301 bt_rc_ctrl_callbacks->connection_state_cb = [](bool /*rc_state*/, bool /*bt_state*/,
302 const RawAddress& /*bd_addr*/) {};
303 BtifRcTest::TearDown();
304 }
305 };
306
TEST_F(BtifRcBrowseConnectionTest,handle_rc_browse_connect)307 TEST_F(BtifRcBrowseConnectionTest, handle_rc_browse_connect) {
308 g_btrc_connection_state_promise = std::promise<rc_connection_state_cb_t>();
309 std::future<rc_connection_state_cb_t> future = g_btrc_connection_state_promise.get_future();
310
311 tBTA_AV_RC_BROWSE_OPEN browse_data = {
312 .rc_handle = 0,
313 .peer_addr = {},
314 .status = BTA_AV_SUCCESS,
315 };
316
317 btif_rc_cb.rc_multi_cb[0].rc_handle = 0;
318 btif_rc_cb.rc_multi_cb[0].rc_addr = RawAddress::kEmpty;
319 btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
320 btif_rc_cb.rc_multi_cb[0].rc_connected = false;
321
322 /* process unit test handle_rc_browse_connect */
323 handle_rc_browse_connect(&browse_data);
324 ASSERT_EQ(std::future_status::ready, future.wait_for(std::chrono::seconds(2)));
325 auto res = future.get();
326 ASSERT_TRUE(res.bt_state);
327 }
328
329 class BtifRcConnectionTest : public BtifRcTest {
330 protected:
SetUp()331 void SetUp() override {
332 BtifRcTest::SetUp();
333 init_ctrl(&btrc_ctrl_callbacks);
334 jni_thread.StartUp();
335 g_btrc_connection_state_promise = std::promise<rc_connection_state_cb_t>();
336 g_btrc_connection_state_future = g_btrc_connection_state_promise.get_future();
337 btrc_ctrl_callbacks.connection_state_cb = [](bool rc_state, bool bt_state,
338 const RawAddress& bd_addr) {
339 rc_connection_state_cb_t rc_connection_state = {
340 .rc_state = rc_state,
341 .bt_state = bt_state,
342 .raw_address = bd_addr,
343 };
344 g_btrc_connection_state_promise.set_value(rc_connection_state);
345 };
346 }
347
TearDown()348 void TearDown() override {
349 jni_thread.ShutDown();
350 bt_rc_ctrl_callbacks->connection_state_cb = [](bool /*rc_state*/, bool /*bt_state*/,
351 const RawAddress& /*bd_addr*/) {};
352 BtifRcTest::TearDown();
353 }
354 std::future<rc_connection_state_cb_t> g_btrc_connection_state_future;
355 };
356
TEST_F(BtifRcConnectionTest,btif_rc_connection_test)357 TEST_F(BtifRcConnectionTest, btif_rc_connection_test) {}
358
TEST_F(BtifRcConnectionTest,handle_rc_browse_connect)359 TEST_F(BtifRcConnectionTest, handle_rc_browse_connect) {
360 tBTA_AV_RC_BROWSE_OPEN browse_data = {
361 .rc_handle = 0,
362 .peer_addr = {},
363 .status = BTA_AV_SUCCESS,
364 };
365
366 btif_rc_cb.rc_multi_cb[0].rc_handle = 0;
367 btif_rc_cb.rc_multi_cb[0].rc_addr = RawAddress::kEmpty;
368 btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
369 btif_rc_cb.rc_multi_cb[0].rc_connected = false;
370
371 /* process unit test handle_rc_browse_connect */
372 handle_rc_browse_connect(&browse_data);
373 ASSERT_EQ(std::future_status::ready,
374 g_btrc_connection_state_future.wait_for(std::chrono::seconds(2)));
375 auto res = g_btrc_connection_state_future.get();
376 ASSERT_TRUE(res.bt_state);
377 }
378
TEST_F(BtifRcConnectionTest,btif_rc_check_pending_cmd)379 TEST_F(BtifRcConnectionTest, btif_rc_check_pending_cmd) {
380 btif_rc_cb.rc_multi_cb[0].rc_handle = 0xff;
381 btif_rc_cb.rc_multi_cb[0].rc_addr = kDeviceAddress;
382 btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
383 btif_rc_cb.rc_multi_cb[0].rc_connected = true;
384 btif_rc_cb.rc_multi_cb[0].launch_cmd_pending |=
385 (RC_PENDING_ACT_REG_VOL | RC_PENDING_ACT_GET_CAP | RC_PENDING_ACT_REPORT_CONN);
386
387 btif_rc_check_pending_cmd(kDeviceAddress);
388 ASSERT_EQ(1, get_func_call_count("AVRC_BldCommand"));
389
390 ASSERT_EQ(std::future_status::ready,
391 g_btrc_connection_state_future.wait_for(std::chrono::seconds(3)));
392 auto res = g_btrc_connection_state_future.get();
393 ASSERT_TRUE(res.rc_state);
394 }
395
TEST_F(BtifRcConnectionTest,bt_av_rc_open_evt)396 TEST_F(BtifRcConnectionTest, bt_av_rc_open_evt) {
397 btrc_ctrl_callbacks.get_cover_art_psm_cb = [](const RawAddress& /* bd_addr */,
398 const uint16_t /* psm */) {};
399 btrc_ctrl_callbacks.getrcfeatures_cb = [](const RawAddress& /* bd_addr */, int /* features */) {};
400
401 /* handle_rc_connect */
402 tBTA_AV data = {
403 .rc_open =
404 {
405 .rc_handle = 0,
406 .cover_art_psm = 0,
407 .peer_features = 0,
408 .peer_ct_features = 0,
409 .peer_tg_features = (BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR |
410 BTA_AV_FEAT_RCTG | BTA_AV_FEAT_RCCT),
411 .peer_addr = kDeviceAddress,
412 .status = BTA_AV_SUCCESS,
413 },
414 };
415 btif_rc_cb.rc_multi_cb[0].rc_handle = 0;
416 btif_rc_cb.rc_multi_cb[0].rc_addr = RawAddress::kEmpty;
417 btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_DISCONNECTED;
418 btif_rc_cb.rc_multi_cb[0].rc_connected = false;
419
420 btif_rc_handler(BTA_AV_RC_OPEN_EVT, &data);
421
422 ASSERT_TRUE(btif_rc_cb.rc_multi_cb[data.rc_open.rc_handle].rc_connected);
423 ASSERT_EQ(btif_rc_cb.rc_multi_cb[data.rc_open.rc_handle].rc_state,
424 BTRC_CONNECTION_STATE_CONNECTED);
425
426 ASSERT_EQ(std::future_status::ready,
427 g_btrc_connection_state_future.wait_for(std::chrono::seconds(2)));
428 auto res = g_btrc_connection_state_future.get();
429 ASSERT_TRUE(res.rc_state);
430 }
431
432 class BtifTrackChangeCBTest : public BtifRcTest {
433 protected:
SetUp()434 void SetUp() override {
435 BtifRcTest::SetUp();
436 init_ctrl(&btrc_ctrl_callbacks);
437 jni_thread.StartUp();
438 btrc_ctrl_callbacks.track_changed_cb = [](const RawAddress& bd_addr, uint8_t /*num_attr*/,
439 btrc_element_attr_val_t* /*p_attrs*/) {
440 btif_rc_cb.rc_multi_cb[0].rc_addr = bd_addr;
441 };
442 }
443
TearDown()444 void TearDown() override {
445 jni_thread.ShutDown();
446 btrc_ctrl_callbacks.track_changed_cb = [](const RawAddress& /*bd_addr*/, uint8_t /*num_attr*/,
447 btrc_element_attr_val_t* /*p_attrs*/) {};
448 BtifRcTest::TearDown();
449 }
450 };
451
TEST_F(BtifTrackChangeCBTest,handle_get_metadata_attr_response)452 TEST_F(BtifTrackChangeCBTest, handle_get_metadata_attr_response) {
453 // Setup an already connected device
454 btif_rc_cb.rc_multi_cb[0].rc_connected = true;
455 btif_rc_cb.rc_multi_cb[0].br_connected = false;
456 btif_rc_cb.rc_multi_cb[0].rc_handle = kRcHandle;
457 btif_rc_cb.rc_multi_cb[0].rc_features = {};
458 btif_rc_cb.rc_multi_cb[0].rc_cover_art_psm = 0;
459 btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
460 btif_rc_cb.rc_multi_cb[0].rc_addr = kDeviceAddress;
461 btif_rc_cb.rc_multi_cb[0].rc_volume = 0;
462 btif_rc_cb.rc_multi_cb[0].rc_vol_label = 0;
463 btif_rc_cb.rc_multi_cb[0].rc_supported_event_list = nullptr;
464 btif_rc_cb.rc_multi_cb[0].rc_app_settings = {};
465 btif_rc_cb.rc_multi_cb[0].rc_play_status_timer = nullptr;
466 btif_rc_cb.rc_multi_cb[0].rc_features_processed = false;
467 btif_rc_cb.rc_multi_cb[0].rc_playing_uid = 0;
468 btif_rc_cb.rc_multi_cb[0].rc_procedure_complete = false;
469 btif_rc_cb.rc_multi_cb[0].peer_ct_features = {};
470 btif_rc_cb.rc_multi_cb[0].peer_tg_features = {};
471 btif_rc_cb.rc_multi_cb[0].launch_cmd_pending = 0;
472 ASSERT_TRUE(btif_rc_get_device_by_handle(kRcHandle));
473
474 tBTA_AV_META_MSG meta_msg = {
475 .rc_handle = kRcHandle,
476 .len = 0,
477 .label = 0,
478 .code{},
479 .company_id = 0,
480 .p_data = {},
481 .p_msg = nullptr,
482 };
483
484 tAVRC_GET_ATTRS_RSP rsp = {
485 .pdu = 0,
486 .status = AVRC_STS_NO_ERROR,
487 .opcode = 0,
488 .num_attrs = 0,
489 .p_attrs = nullptr,
490 };
491
492 handle_get_metadata_attr_response(&meta_msg, &rsp);
493
494 ASSERT_EQ(1, get_func_call_count("osi_free_and_reset"));
495 }
496