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 "test/common/mock_functions.h"
33 #include "test/mock/mock_osi_alarm.h"
34 #include "test/mock/mock_osi_allocator.h"
35 #include "test/mock/mock_osi_list.h"
36 #include "types/raw_address.h"
37 
38 namespace bluetooth {
39 namespace avrcp {
40 int VolChanged = 0;
41 AvrcpService* AvrcpService::instance_ = nullptr;
42 
SendMediaUpdate(bool track_changed,bool play_state,bool queue)43 void AvrcpService::SendMediaUpdate(bool track_changed, bool play_state,
44                                    bool queue){};
SendFolderUpdate(bool available_players,bool addressed_players,bool uids)45 void AvrcpService::SendFolderUpdate(bool available_players,
46                                     bool addressed_players, bool uids){};
SendActiveDeviceChanged(const RawAddress & address)47 void AvrcpService::SendActiveDeviceChanged(const RawAddress& address){};
SendPlayerSettingsChanged(std::vector<PlayerAttribute> attributes,std::vector<uint8_t> values)48 void AvrcpService::SendPlayerSettingsChanged(
49     std::vector<PlayerAttribute> attributes, std::vector<uint8_t> values){};
Init(MediaInterface * media_interface,VolumeInterface * volume_interface,PlayerSettingsInterface * player_settings_interface)50 void AvrcpService::ServiceInterfaceImpl::Init(
51     MediaInterface* media_interface, VolumeInterface* volume_interface,
52     PlayerSettingsInterface* player_settings_interface){};
RegisterBipServer(int psm)53 void AvrcpService::ServiceInterfaceImpl::RegisterBipServer(int psm){};
UnregisterBipServer()54 void AvrcpService::ServiceInterfaceImpl::UnregisterBipServer(){};
ConnectDevice(const RawAddress & bdaddr)55 bool AvrcpService::ServiceInterfaceImpl::ConnectDevice(
56     const RawAddress& bdaddr) {
57   return true;
58 };
DisconnectDevice(const RawAddress & bdaddr)59 bool AvrcpService::ServiceInterfaceImpl::DisconnectDevice(
60     const RawAddress& bdaddr) {
61   return true;
62 };
SetBipClientStatus(const RawAddress & bdaddr,bool connected)63 void AvrcpService::ServiceInterfaceImpl::SetBipClientStatus(
64     const RawAddress& bdaddr, bool connected){};
Cleanup()65 bool AvrcpService::ServiceInterfaceImpl::Cleanup() { return true; };
66 
Get()67 AvrcpService* AvrcpService::Get() {
68   EXPECT_EQ(instance_, nullptr);
69   instance_ = new AvrcpService();
70   return instance_;
71 }
72 
RegisterVolChanged(const RawAddress & bdaddr)73 void AvrcpService::RegisterVolChanged(const RawAddress& bdaddr) {
74   VolChanged++;
75 }
76 }  // namespace avrcp
77 }  // namespace bluetooth
78 
79 namespace {
80 const RawAddress kDeviceAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
81 const uint8_t kRcHandle = 123;
82 }  // namespace
83 
btif_av_clear_remote_suspend_flag(const A2dpType local_a2dp_type)84 void btif_av_clear_remote_suspend_flag(const A2dpType local_a2dp_type) {}
btif_av_is_connected(const A2dpType local_a2dp_type)85 bool btif_av_is_connected(const A2dpType local_a2dp_type) { return true; }
btif_av_is_sink_enabled(void)86 bool btif_av_is_sink_enabled(void) { return true; }
btif_av_sink_active_peer(void)87 RawAddress btif_av_sink_active_peer(void) { return RawAddress(); }
btif_av_source_active_peer(void)88 RawAddress btif_av_source_active_peer(void) { return RawAddress(); }
btif_av_stream_started_ready(const A2dpType local_a2dp_type)89 bool btif_av_stream_started_ready(const A2dpType local_a2dp_type) {
90   return false;
91 }
btif_transfer_context(tBTIF_CBACK * p_cback,uint16_t event,char * p_params,int param_len,tBTIF_COPY_CBACK * p_copy_cback)92 bt_status_t btif_transfer_context(tBTIF_CBACK* p_cback, uint16_t event,
93                                   char* p_params, int param_len,
94                                   tBTIF_COPY_CBACK* p_copy_cback) {
95   return BT_STATUS_SUCCESS;
96 }
btif_av_src_sink_coexist_enabled()97 bool btif_av_src_sink_coexist_enabled() { return true; }
btif_av_is_connected_addr(const RawAddress & peer_address,const A2dpType local_a2dp_type)98 bool btif_av_is_connected_addr(const RawAddress& peer_address,
99                                const A2dpType local_a2dp_type) {
100   return true;
101 }
btif_av_peer_is_connected_sink(const RawAddress & peer_address)102 bool btif_av_peer_is_connected_sink(const RawAddress& peer_address) {
103   return false;
104 }
btif_av_peer_is_connected_source(const RawAddress & peer_address)105 bool btif_av_peer_is_connected_source(const RawAddress& peer_address) {
106   return true;
107 }
btif_av_peer_is_sink(const RawAddress & peer_address)108 bool btif_av_peer_is_sink(const RawAddress& peer_address) { return false; }
btif_av_peer_is_source(const RawAddress & peer_address)109 bool btif_av_peer_is_source(const RawAddress& peer_address) { return true; }
btif_av_both_enable(void)110 bool btif_av_both_enable(void) { return true; }
111 
112 static bluetooth::common::MessageLoopThread jni_thread("bt_jni_thread");
do_in_jni_thread(base::OnceClosure task)113 bt_status_t do_in_jni_thread(base::OnceClosure task) {
114   if (!jni_thread.DoInThread(FROM_HERE, std::move(task))) {
115     log::error("Post task to task runner failed!");
116     return BT_STATUS_JNI_THREAD_ATTACH_ERROR;
117   }
118   return BT_STATUS_SUCCESS;
119 }
get_main_thread()120 bluetooth::common::MessageLoopThread* get_main_thread() { return nullptr; }
interop_match_addr(const interop_feature_t feature,const RawAddress * addr)121 bool interop_match_addr(const interop_feature_t feature,
122                         const RawAddress* addr) {
123   return false;
124 }
125 
126 /**
127  * Test class to test selected functionality in hci/src/hci_layer.cc
128  */
129 class BtifRcTest : public ::testing::Test {
130  protected:
SetUp()131   void SetUp() override { reset_mock_function_count_map(); }
TearDown()132   void TearDown() override {}
133 };
134 
TEST_F(BtifRcTest,get_element_attr_rsp)135 TEST_F(BtifRcTest, get_element_attr_rsp) {
136   btif_rc_cb.rc_multi_cb[0].rc_addr = kDeviceAddress;
137   btif_rc_cb.rc_multi_cb[0].rc_connected = true;
138   btif_rc_cb.rc_multi_cb[0]
139       .rc_pdu_info[IDX_GET_ELEMENT_ATTR_RSP]
140       .is_rsp_pending = true;
141   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
142 
143   btrc_element_attr_val_t p_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
144   uint8_t num_attr = BTRC_MAX_ELEM_ATTR_SIZE + 1;
145 
146   ASSERT_EQ(get_element_attr_rsp(kDeviceAddress, num_attr, p_attrs),
147             BT_STATUS_SUCCESS);
148   ASSERT_EQ(1, get_func_call_count("AVRC_BldResponse"));
149 }
150 
TEST_F(BtifRcTest,btif_rc_get_addr_by_handle)151 TEST_F(BtifRcTest, btif_rc_get_addr_by_handle) {
152   RawAddress bd_addr;
153 
154   btif_rc_cb.rc_multi_cb[0].rc_addr = kDeviceAddress;
155   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
156   btif_rc_cb.rc_multi_cb[0].rc_handle = 0;
157 
158   btif_rc_get_addr_by_handle(0, bd_addr);
159   ASSERT_EQ(kDeviceAddress, bd_addr);
160 }
161 
162 static btrc_ctrl_callbacks_t default_btrc_ctrl_callbacks = {
163     .size = sizeof(btrc_ctrl_callbacks_t),
164     .passthrough_rsp_cb = [](const RawAddress& /* bd_addr */, int /* id */,
__anoneceeb2bd0202() 165                              int /* key_state */) { FAIL(); },
__anoneceeb2bd0302() 166     .groupnavigation_rsp_cb = [](int /* id */, int /* key_state */) { FAIL(); },
167     .connection_state_cb = [](bool /* rc_connect */, bool /* bt_connect */,
__anoneceeb2bd0402() 168                               const RawAddress& /* bd_addr */) { FAIL(); },
169     .getrcfeatures_cb = [](const RawAddress& /* bd_addr */,
__anoneceeb2bd0502() 170                            int /* features */) { FAIL(); },
171     .setplayerappsetting_rsp_cb = [](const RawAddress& /* bd_addr */,
__anoneceeb2bd0602() 172                                      uint8_t /* accepted */) { FAIL(); },
173     .playerapplicationsetting_cb =
174         [](const RawAddress& /* bd_addr */, uint8_t /* num_attr */,
175            btrc_player_app_attr_t* /* app_attrs */, uint8_t /* num_ext_attr */,
__anoneceeb2bd0702() 176            btrc_player_app_ext_attr_t* /* ext_attrs */) { FAIL(); },
177     .playerapplicationsetting_changed_cb =
178         [](const RawAddress& /* bd_addr */,
__anoneceeb2bd0802() 179            const btrc_player_settings_t& /* vals */) { FAIL(); },
180     .setabsvol_cmd_cb = [](const RawAddress& /* bd_addr */,
181                            uint8_t /* abs_vol */,
__anoneceeb2bd0902() 182                            uint8_t /* label */) { FAIL(); },
183     .registernotification_absvol_cb = [](const RawAddress& /* bd_addr */,
__anoneceeb2bd0a02() 184                                          uint8_t /* label */) { FAIL(); },
185     .track_changed_cb = [](const RawAddress& /* bd_addr */,
186                            uint8_t /* num_attr */,
__anoneceeb2bd0b02() 187                            btrc_element_attr_val_t* /* p_attrs */) { FAIL(); },
188     .play_position_changed_cb = [](const RawAddress& /* bd_addr */,
189                                    uint32_t /* song_len */,
__anoneceeb2bd0c02() 190                                    uint32_t /* song_pos */) { FAIL(); },
191     .play_status_changed_cb =
192         [](const RawAddress& /* bd_addr */,
__anoneceeb2bd0d02() 193            btrc_play_status_t /* play_status */) { FAIL(); },
194     .get_folder_items_cb = [](const RawAddress& /* bd_addr */,
195                               btrc_status_t /* status */,
196                               const btrc_folder_items_t* /* folder_items */,
__anoneceeb2bd0e02() 197                               uint8_t /* count */) { FAIL(); },
198     .change_folder_path_cb = [](const RawAddress& /* bd_addr */,
__anoneceeb2bd0f02() 199                                 uint32_t /* count */) { FAIL(); },
200     .set_browsed_player_cb = [](const RawAddress& /* bd_addr */,
201                                 uint8_t /* num_items */,
__anoneceeb2bd1002() 202                                 uint8_t /* depth */) { FAIL(); },
203     .set_addressed_player_cb = [](const RawAddress& /* bd_addr */,
__anoneceeb2bd1102() 204                                   uint8_t /* status */) { FAIL(); },
205     .addressed_player_changed_cb = [](const RawAddress& /* bd_addr */,
__anoneceeb2bd1202() 206                                       uint16_t /* id */) { FAIL(); },
207     .now_playing_contents_changed_cb =
__anoneceeb2bd1302() 208         [](const RawAddress& /* bd_addr */) { FAIL(); },
209     .available_player_changed_cb =
__anoneceeb2bd1402() 210         [](const RawAddress& /* bd_addr */) { FAIL(); },
211     .get_cover_art_psm_cb = [](const RawAddress& /* bd_addr */,
__anoneceeb2bd1502() 212                                const uint16_t /* psm */) { FAIL(); },
213 };
214 static btrc_ctrl_callbacks_t btrc_ctrl_callbacks = default_btrc_ctrl_callbacks;
215 
216 struct rc_connection_state_cb_t {
217   bool rc_state;
218   bool bt_state;
219   RawAddress raw_address;
220 };
221 
222 struct rc_feature_cb_t {
223   int feature;
224   RawAddress raw_address;
225 };
226 
227 static std::promise<rc_connection_state_cb_t> g_btrc_connection_state_promise;
228 static std::promise<rc_feature_cb_t> g_btrc_feature;
229 
230 class BtifRcWithCallbacksTest : public BtifRcTest {
231  protected:
SetUp()232   void SetUp() override {
233     BtifRcTest::SetUp();
234     btrc_ctrl_callbacks = default_btrc_ctrl_callbacks;
235     init_ctrl(&btrc_ctrl_callbacks);
236     jni_thread.StartUp();
237     btrc_ctrl_callbacks.getrcfeatures_cb = [](const RawAddress& bd_addr,
238                                               int features) {
239       rc_feature_cb_t rc_feature = {
240           .feature = features,
241           .raw_address = bd_addr,
242       };
243       g_btrc_feature.set_value(rc_feature);
244     };
245   }
246 
TearDown()247   void TearDown() override {
248     jni_thread.ShutDown();
249     bt_rc_ctrl_callbacks->getrcfeatures_cb = [](const RawAddress& bd_addr,
250                                                 int features) {};
251     btrc_ctrl_callbacks = default_btrc_ctrl_callbacks;
252     BtifRcTest::TearDown();
253   }
254 };
255 
TEST_F(BtifRcWithCallbacksTest,handle_rc_ctrl_features)256 TEST_F(BtifRcWithCallbacksTest, handle_rc_ctrl_features) {
257   g_btrc_feature = std::promise<rc_feature_cb_t>();
258   std::future<rc_feature_cb_t> future = g_btrc_feature.get_future();
259   btif_rc_device_cb_t p_dev;
260 
261   p_dev.peer_tg_features =
262       (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_RCCT |
263        BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_BROWSE |
264        BTA_AV_FEAT_COVER_ARTWORK);
265   p_dev.rc_connected = true;
266 
267   handle_rc_ctrl_features(&p_dev);
268   ASSERT_EQ(1, get_func_call_count("AVRC_BldCommand"));
269 
270   ASSERT_EQ(std::future_status::ready,
271             future.wait_for(std::chrono::seconds(2)));
272   auto res = future.get();
273   log::info("FEATURES:{}", res.feature);
274   ASSERT_EQ(res.feature, (BTRC_FEAT_ABSOLUTE_VOLUME | BTRC_FEAT_METADATA |
275                           BTRC_FEAT_BROWSE | BTRC_FEAT_COVER_ARTWORK));
276 }
277 
278 class BtifRcBrowseConnectionTest : public BtifRcTest {
279  protected:
SetUp()280   void SetUp() override {
281     BtifRcTest::SetUp();
282     init_ctrl(&btrc_ctrl_callbacks);
283     jni_thread.StartUp();
284     btrc_ctrl_callbacks.connection_state_cb = [](bool rc_state, bool bt_state,
285                                                  const RawAddress& bd_addr) {
286       rc_connection_state_cb_t rc_connection_state = {
287           .rc_state = rc_state,
288           .bt_state = bt_state,
289           .raw_address = bd_addr,
290       };
291       g_btrc_connection_state_promise.set_value(rc_connection_state);
292     };
293   }
294 
TearDown()295   void TearDown() override {
296     jni_thread.ShutDown();
297     bt_rc_ctrl_callbacks->connection_state_cb =
298         [](bool rc_state, bool bt_state, const RawAddress& bd_addr) {};
299     BtifRcTest::TearDown();
300   }
301 };
302 
TEST_F(BtifRcBrowseConnectionTest,handle_rc_browse_connect)303 TEST_F(BtifRcBrowseConnectionTest, handle_rc_browse_connect) {
304   g_btrc_connection_state_promise = std::promise<rc_connection_state_cb_t>();
305   std::future<rc_connection_state_cb_t> future =
306       g_btrc_connection_state_promise.get_future();
307 
308   tBTA_AV_RC_BROWSE_OPEN browse_data = {
309       .rc_handle = 0,
310       .peer_addr = {},
311       .status = BTA_AV_SUCCESS,
312   };
313 
314   btif_rc_cb.rc_multi_cb[0].rc_handle = 0;
315   btif_rc_cb.rc_multi_cb[0].rc_addr = RawAddress::kEmpty;
316   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
317   btif_rc_cb.rc_multi_cb[0].rc_connected = false;
318 
319   /* process unit test  handle_rc_browse_connect */
320   handle_rc_browse_connect(&browse_data);
321   ASSERT_EQ(std::future_status::ready,
322             future.wait_for(std::chrono::seconds(2)));
323   auto res = future.get();
324   ASSERT_TRUE(res.bt_state);
325 }
326 
327 class BtifRcConnectionTest : public BtifRcTest {
328  protected:
SetUp()329   void SetUp() override {
330     BtifRcTest::SetUp();
331     init_ctrl(&btrc_ctrl_callbacks);
332     jni_thread.StartUp();
333     g_btrc_connection_state_promise = std::promise<rc_connection_state_cb_t>();
334     g_btrc_connection_state_future =
335         g_btrc_connection_state_promise.get_future();
336     btrc_ctrl_callbacks.connection_state_cb = [](bool rc_state, bool bt_state,
337                                                  const RawAddress& bd_addr) {
338       rc_connection_state_cb_t rc_connection_state = {
339           .rc_state = rc_state,
340           .bt_state = bt_state,
341           .raw_address = bd_addr,
342       };
343       g_btrc_connection_state_promise.set_value(rc_connection_state);
344     };
345   }
346 
TearDown()347   void TearDown() override {
348     jni_thread.ShutDown();
349     bt_rc_ctrl_callbacks->connection_state_cb =
350         [](bool rc_state, bool bt_state, const RawAddress& bd_addr) {};
351     BtifRcTest::TearDown();
352   }
353   std::future<rc_connection_state_cb_t> g_btrc_connection_state_future;
354 };
355 
TEST_F(BtifRcConnectionTest,btif_rc_connection_test)356 TEST_F(BtifRcConnectionTest, btif_rc_connection_test) {}
357 
TEST_F(BtifRcConnectionTest,handle_rc_browse_connect)358 TEST_F(BtifRcConnectionTest, handle_rc_browse_connect) {
359   tBTA_AV_RC_BROWSE_OPEN browse_data = {
360       .rc_handle = 0,
361       .peer_addr = {},
362       .status = BTA_AV_SUCCESS,
363   };
364 
365   btif_rc_cb.rc_multi_cb[0].rc_handle = 0;
366   btif_rc_cb.rc_multi_cb[0].rc_addr = RawAddress::kEmpty;
367   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
368   btif_rc_cb.rc_multi_cb[0].rc_connected = false;
369 
370   /* process unit test  handle_rc_browse_connect */
371   handle_rc_browse_connect(&browse_data);
372   ASSERT_EQ(std::future_status::ready,
373             g_btrc_connection_state_future.wait_for(std::chrono::seconds(2)));
374   auto res = g_btrc_connection_state_future.get();
375   ASSERT_TRUE(res.bt_state);
376 }
377 
TEST_F(BtifRcConnectionTest,btif_rc_check_pending_cmd)378 TEST_F(BtifRcConnectionTest, btif_rc_check_pending_cmd) {
379   btif_rc_cb.rc_multi_cb[0].rc_handle = 0xff;
380   btif_rc_cb.rc_multi_cb[0].rc_addr = kDeviceAddress;
381   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
382   btif_rc_cb.rc_multi_cb[0].rc_connected = true;
383   btif_rc_cb.rc_multi_cb[0].launch_cmd_pending |=
384       (RC_PENDING_ACT_REG_VOL | RC_PENDING_ACT_GET_CAP |
385        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 */,
400                                             int /* features */) {};
401 
402   /* handle_rc_connect  */
403   tBTA_AV data = {
404       .rc_open =
405           {
406               .rc_handle = 0,
407               .cover_art_psm = 0,
408               .peer_features = 0,
409               .peer_ct_features = 0,
410               .peer_tg_features = (BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR |
411                                    BTA_AV_FEAT_RCTG | BTA_AV_FEAT_RCCT),
412               .peer_addr = kDeviceAddress,
413               .status = BTA_AV_SUCCESS,
414           },
415   };
416   btif_rc_cb.rc_multi_cb[0].rc_handle = 0;
417   btif_rc_cb.rc_multi_cb[0].rc_addr = RawAddress::kEmpty;
418   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_DISCONNECTED;
419   btif_rc_cb.rc_multi_cb[0].rc_connected = false;
420 
421   btif_rc_handler(BTA_AV_RC_OPEN_EVT, &data);
422 
423   ASSERT_TRUE(btif_rc_cb.rc_multi_cb[data.rc_open.rc_handle].rc_connected);
424   ASSERT_EQ(btif_rc_cb.rc_multi_cb[data.rc_open.rc_handle].rc_state,
425             BTRC_CONNECTION_STATE_CONNECTED);
426 
427   ASSERT_EQ(std::future_status::ready,
428             g_btrc_connection_state_future.wait_for(std::chrono::seconds(2)));
429   auto res = g_btrc_connection_state_future.get();
430   ASSERT_TRUE(res.rc_state);
431 }
432 
433 class BtifTrackChangeCBTest : public BtifRcTest {
434  protected:
SetUp()435   void SetUp() override {
436     BtifRcTest::SetUp();
437     init_ctrl(&btrc_ctrl_callbacks);
438     jni_thread.StartUp();
439     btrc_ctrl_callbacks.track_changed_cb = [](const RawAddress& bd_addr,
440                        uint8_t num_attr, btrc_element_attr_val_t* p_attrs) {
441       btif_rc_cb.rc_multi_cb[0].rc_addr = bd_addr;
442     };
443   }
444 
TearDown()445   void TearDown() override {
446     jni_thread.ShutDown();
447     btrc_ctrl_callbacks.track_changed_cb = [](const RawAddress& bd_addr,
448                        uint8_t num_attr, btrc_element_attr_val_t* p_attrs) {};
449     BtifRcTest::TearDown();
450   }
451 };
452 
TEST_F(BtifTrackChangeCBTest,handle_get_metadata_attr_response)453 TEST_F(BtifTrackChangeCBTest, handle_get_metadata_attr_response) {
454   // Setup an already connected device
455   btif_rc_cb.rc_multi_cb[0].rc_connected = true;
456   btif_rc_cb.rc_multi_cb[0].br_connected = false;
457   btif_rc_cb.rc_multi_cb[0].rc_handle = kRcHandle;
458   btif_rc_cb.rc_multi_cb[0].rc_features = {};
459   btif_rc_cb.rc_multi_cb[0].rc_cover_art_psm = 0;
460   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
461   btif_rc_cb.rc_multi_cb[0].rc_addr = kDeviceAddress;
462   btif_rc_cb.rc_multi_cb[0].rc_pending_play = 0;
463   btif_rc_cb.rc_multi_cb[0].rc_volume = 0;
464   btif_rc_cb.rc_multi_cb[0].rc_vol_label = 0;
465   btif_rc_cb.rc_multi_cb[0].rc_supported_event_list = nullptr;
466   btif_rc_cb.rc_multi_cb[0].rc_app_settings = {};
467   btif_rc_cb.rc_multi_cb[0].rc_play_status_timer = nullptr;
468   btif_rc_cb.rc_multi_cb[0].rc_features_processed = false;
469   btif_rc_cb.rc_multi_cb[0].rc_playing_uid = 0;
470   btif_rc_cb.rc_multi_cb[0].rc_procedure_complete = false;
471   btif_rc_cb.rc_multi_cb[0].peer_ct_features = {};
472   btif_rc_cb.rc_multi_cb[0].peer_tg_features = {};
473   btif_rc_cb.rc_multi_cb[0].launch_cmd_pending = 0;
474   ASSERT_TRUE(btif_rc_get_device_by_handle(kRcHandle));
475 
476   tBTA_AV_META_MSG meta_msg = {
477       .rc_handle = kRcHandle,
478       .len = 0,
479       .label = 0,
480       .code{},
481       .company_id = 0,
482       .p_data = {},
483       .p_msg = nullptr,
484   };
485 
486   tAVRC_GET_ATTRS_RSP rsp = {
487       .pdu = 0,
488       .status = AVRC_STS_NO_ERROR,
489       .opcode = 0,
490       .num_attrs = 0,
491       .p_attrs = nullptr,
492   };
493 
494   handle_get_metadata_attr_response(&meta_msg, &rsp);
495 
496   ASSERT_EQ(1, get_func_call_count("osi_free_and_reset"));
497 }
498