• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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