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(FROM_HERE, 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,get_element_attr_rsp)122 TEST_F(BtifRcTest, get_element_attr_rsp) {
123   btif_rc_cb.rc_multi_cb[0].rc_addr = kDeviceAddress;
124   btif_rc_cb.rc_multi_cb[0].rc_connected = true;
125   btif_rc_cb.rc_multi_cb[0].rc_pdu_info[IDX_GET_ELEMENT_ATTR_RSP].is_rsp_pending = true;
126   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
127 
128   btrc_element_attr_val_t p_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
129   uint8_t num_attr = BTRC_MAX_ELEM_ATTR_SIZE + 1;
130 
131   ASSERT_EQ(get_element_attr_rsp(kDeviceAddress, num_attr, p_attrs), BT_STATUS_SUCCESS);
132   ASSERT_EQ(1, get_func_call_count("AVRC_BldResponse"));
133 }
134 
TEST_F(BtifRcTest,btif_rc_get_addr_by_handle)135 TEST_F(BtifRcTest, btif_rc_get_addr_by_handle) {
136   RawAddress bd_addr;
137 
138   btif_rc_cb.rc_multi_cb[0].rc_addr = kDeviceAddress;
139   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
140   btif_rc_cb.rc_multi_cb[0].rc_handle = 0;
141 
142   btif_rc_get_addr_by_handle(0, bd_addr);
143   ASSERT_EQ(kDeviceAddress, bd_addr);
144 }
145 
146 static btrc_ctrl_callbacks_t default_btrc_ctrl_callbacks = {
147         .size = sizeof(btrc_ctrl_callbacks_t),
148         .passthrough_rsp_cb = [](const RawAddress& /* bd_addr */, int /* id */,
__anon3fbae4330202() 149                                  int /* key_state */) { FAIL(); },
__anon3fbae4330302() 150         .groupnavigation_rsp_cb = [](int /* id */, int /* key_state */) { FAIL(); },
151         .connection_state_cb = [](bool /* rc_connect */, bool /* bt_connect */,
__anon3fbae4330402() 152                                   const RawAddress& /* bd_addr */) { FAIL(); },
__anon3fbae4330502() 153         .getrcfeatures_cb = [](const RawAddress& /* bd_addr */, int /* features */) { FAIL(); },
154         .setplayerappsetting_rsp_cb = [](const RawAddress& /* bd_addr */,
__anon3fbae4330602() 155                                          uint8_t /* accepted */) { FAIL(); },
156         .playerapplicationsetting_cb = [](const RawAddress& /* bd_addr */, uint8_t /* num_attr */,
157                                           btrc_player_app_attr_t* /* app_attrs */,
158                                           uint8_t /* num_ext_attr */,
__anon3fbae4330702() 159                                           btrc_player_app_ext_attr_t* /* ext_attrs */) { FAIL(); },
160         .playerapplicationsetting_changed_cb =
__anon3fbae4330802() 161                 [](const RawAddress& /* bd_addr */, const btrc_player_settings_t& /* vals */) {
162                   FAIL();
163                 },
164         .setabsvol_cmd_cb = [](const RawAddress& /* bd_addr */, uint8_t /* abs_vol */,
__anon3fbae4330902() 165                                uint8_t /* label */) { FAIL(); },
166         .registernotification_absvol_cb = [](const RawAddress& /* bd_addr */,
__anon3fbae4330a02() 167                                              uint8_t /* label */) { FAIL(); },
168         .track_changed_cb = [](const RawAddress& /* bd_addr */, uint8_t /* num_attr */,
__anon3fbae4330b02() 169                                btrc_element_attr_val_t* /* p_attrs */) { FAIL(); },
170         .play_position_changed_cb = [](const RawAddress& /* bd_addr */, uint32_t /* song_len */,
__anon3fbae4330c02() 171                                        uint32_t /* song_pos */) { FAIL(); },
172         .play_status_changed_cb = [](const RawAddress& /* bd_addr */,
__anon3fbae4330d02() 173                                      btrc_play_status_t /* play_status */) { FAIL(); },
174         .get_folder_items_cb = [](const RawAddress& /* bd_addr */, btrc_status_t /* status */,
175                                   const btrc_folder_items_t* /* folder_items */,
__anon3fbae4330e02() 176                                   uint8_t /* count */) { FAIL(); },
177         .change_folder_path_cb = [](const RawAddress& /* bd_addr */,
__anon3fbae4330f02() 178                                     uint32_t /* count */) { FAIL(); },
179         .set_browsed_player_cb = [](const RawAddress& /* bd_addr */, uint8_t /* num_items */,
__anon3fbae4331002() 180                                     uint8_t /* depth */) { FAIL(); },
181         .set_addressed_player_cb = [](const RawAddress& /* bd_addr */,
__anon3fbae4331102() 182                                       uint8_t /* status */) { FAIL(); },
183         .addressed_player_changed_cb = [](const RawAddress& /* bd_addr */,
__anon3fbae4331202() 184                                           uint16_t /* id */) { FAIL(); },
__anon3fbae4331302() 185         .now_playing_contents_changed_cb = [](const RawAddress& /* bd_addr */) { FAIL(); },
__anon3fbae4331402() 186         .available_player_changed_cb = [](const RawAddress& /* bd_addr */) { FAIL(); },
187         .get_cover_art_psm_cb = [](const RawAddress& /* bd_addr */,
__anon3fbae4331502() 188                                    const uint16_t /* psm */) { FAIL(); },
189 };
190 static btrc_ctrl_callbacks_t btrc_ctrl_callbacks = default_btrc_ctrl_callbacks;
191 
192 struct rc_connection_state_cb_t {
193   bool rc_state;
194   bool bt_state;
195   RawAddress raw_address;
196 };
197 
198 struct rc_feature_cb_t {
199   int feature;
200   RawAddress raw_address;
201 };
202 
203 static std::promise<rc_connection_state_cb_t> g_btrc_connection_state_promise;
204 static std::promise<rc_feature_cb_t> g_btrc_feature;
205 
206 class BtifRcWithCallbacksTest : public BtifRcTest {
207 protected:
SetUp()208   void SetUp() override {
209     BtifRcTest::SetUp();
210     btrc_ctrl_callbacks = default_btrc_ctrl_callbacks;
211     init_ctrl(&btrc_ctrl_callbacks);
212     jni_thread.StartUp();
213     btrc_ctrl_callbacks.getrcfeatures_cb = [](const RawAddress& bd_addr, int features) {
214       rc_feature_cb_t rc_feature = {
215               .feature = features,
216               .raw_address = bd_addr,
217       };
218       g_btrc_feature.set_value(rc_feature);
219     };
220   }
221 
TearDown()222   void TearDown() override {
223     jni_thread.ShutDown();
224     bt_rc_ctrl_callbacks->getrcfeatures_cb = [](const RawAddress& /*bd_addr*/, int /*features*/) {};
225     btrc_ctrl_callbacks = default_btrc_ctrl_callbacks;
226     BtifRcTest::TearDown();
227   }
228 };
229 
TEST_F(BtifRcWithCallbacksTest,handle_rc_ctrl_features)230 TEST_F(BtifRcWithCallbacksTest, handle_rc_ctrl_features) {
231   g_btrc_feature = std::promise<rc_feature_cb_t>();
232   std::future<rc_feature_cb_t> future = g_btrc_feature.get_future();
233   btif_rc_device_cb_t p_dev;
234 
235   p_dev.peer_tg_features =
236           (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_ADV_CTRL | BTA_AV_FEAT_RCCT | BTA_AV_FEAT_METADATA |
237            BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_BROWSE | BTA_AV_FEAT_COVER_ARTWORK);
238   p_dev.rc_connected = true;
239 
240   handle_rc_ctrl_features(&p_dev);
241   ASSERT_EQ(1, get_func_call_count("AVRC_BldCommand"));
242 
243   ASSERT_EQ(std::future_status::ready, future.wait_for(std::chrono::seconds(2)));
244   auto res = future.get();
245   log::info("FEATURES:{}", res.feature);
246   ASSERT_EQ(res.feature, (BTRC_FEAT_ABSOLUTE_VOLUME | BTRC_FEAT_METADATA | BTRC_FEAT_BROWSE |
247                           BTRC_FEAT_COVER_ARTWORK));
248 }
249 
250 class BtifRcBrowseConnectionTest : public BtifRcTest {
251 protected:
SetUp()252   void SetUp() override {
253     BtifRcTest::SetUp();
254     init_ctrl(&btrc_ctrl_callbacks);
255     jni_thread.StartUp();
256     btrc_ctrl_callbacks.connection_state_cb = [](bool rc_state, bool bt_state,
257                                                  const RawAddress& bd_addr) {
258       rc_connection_state_cb_t rc_connection_state = {
259               .rc_state = rc_state,
260               .bt_state = bt_state,
261               .raw_address = bd_addr,
262       };
263       g_btrc_connection_state_promise.set_value(rc_connection_state);
264     };
265   }
266 
TearDown()267   void TearDown() override {
268     jni_thread.ShutDown();
269     bt_rc_ctrl_callbacks->connection_state_cb = [](bool /*rc_state*/, bool /*bt_state*/,
270                                                    const RawAddress& /*bd_addr*/) {};
271     BtifRcTest::TearDown();
272   }
273 };
274 
TEST_F(BtifRcBrowseConnectionTest,handle_rc_browse_connect)275 TEST_F(BtifRcBrowseConnectionTest, handle_rc_browse_connect) {
276   g_btrc_connection_state_promise = std::promise<rc_connection_state_cb_t>();
277   std::future<rc_connection_state_cb_t> future = g_btrc_connection_state_promise.get_future();
278 
279   tBTA_AV_RC_BROWSE_OPEN browse_data = {
280           .rc_handle = 0,
281           .peer_addr = {},
282           .status = BTA_AV_SUCCESS,
283   };
284 
285   btif_rc_cb.rc_multi_cb[0].rc_handle = 0;
286   btif_rc_cb.rc_multi_cb[0].rc_addr = RawAddress::kEmpty;
287   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
288   btif_rc_cb.rc_multi_cb[0].rc_connected = false;
289 
290   /* process unit test  handle_rc_browse_connect */
291   handle_rc_browse_connect(&browse_data);
292   ASSERT_EQ(std::future_status::ready, future.wait_for(std::chrono::seconds(2)));
293   auto res = future.get();
294   ASSERT_TRUE(res.bt_state);
295 }
296 
297 class BtifRcConnectionTest : public BtifRcTest {
298 protected:
SetUp()299   void SetUp() override {
300     BtifRcTest::SetUp();
301     init_ctrl(&btrc_ctrl_callbacks);
302     jni_thread.StartUp();
303     g_btrc_connection_state_promise = std::promise<rc_connection_state_cb_t>();
304     g_btrc_connection_state_future = g_btrc_connection_state_promise.get_future();
305     btrc_ctrl_callbacks.connection_state_cb = [](bool rc_state, bool bt_state,
306                                                  const RawAddress& bd_addr) {
307       rc_connection_state_cb_t rc_connection_state = {
308               .rc_state = rc_state,
309               .bt_state = bt_state,
310               .raw_address = bd_addr,
311       };
312       g_btrc_connection_state_promise.set_value(rc_connection_state);
313     };
314   }
315 
TearDown()316   void TearDown() override {
317     jni_thread.ShutDown();
318     bt_rc_ctrl_callbacks->connection_state_cb = [](bool /*rc_state*/, bool /*bt_state*/,
319                                                    const RawAddress& /*bd_addr*/) {};
320     BtifRcTest::TearDown();
321   }
322   std::future<rc_connection_state_cb_t> g_btrc_connection_state_future;
323 };
324 
TEST_F(BtifRcConnectionTest,btif_rc_connection_test)325 TEST_F(BtifRcConnectionTest, btif_rc_connection_test) {}
326 
TEST_F(BtifRcConnectionTest,handle_rc_browse_connect)327 TEST_F(BtifRcConnectionTest, handle_rc_browse_connect) {
328   tBTA_AV_RC_BROWSE_OPEN browse_data = {
329           .rc_handle = 0,
330           .peer_addr = {},
331           .status = BTA_AV_SUCCESS,
332   };
333 
334   btif_rc_cb.rc_multi_cb[0].rc_handle = 0;
335   btif_rc_cb.rc_multi_cb[0].rc_addr = RawAddress::kEmpty;
336   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
337   btif_rc_cb.rc_multi_cb[0].rc_connected = false;
338 
339   /* process unit test  handle_rc_browse_connect */
340   handle_rc_browse_connect(&browse_data);
341   ASSERT_EQ(std::future_status::ready,
342             g_btrc_connection_state_future.wait_for(std::chrono::seconds(2)));
343   auto res = g_btrc_connection_state_future.get();
344   ASSERT_TRUE(res.bt_state);
345 }
346 
TEST_F(BtifRcConnectionTest,btif_rc_check_pending_cmd)347 TEST_F(BtifRcConnectionTest, btif_rc_check_pending_cmd) {
348   btif_rc_cb.rc_multi_cb[0].rc_handle = 0xff;
349   btif_rc_cb.rc_multi_cb[0].rc_addr = kDeviceAddress;
350   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
351   btif_rc_cb.rc_multi_cb[0].rc_connected = true;
352   btif_rc_cb.rc_multi_cb[0].launch_cmd_pending |=
353           (RC_PENDING_ACT_REG_VOL | RC_PENDING_ACT_GET_CAP | RC_PENDING_ACT_REPORT_CONN);
354 
355   btif_rc_check_pending_cmd(kDeviceAddress);
356   ASSERT_EQ(1, get_func_call_count("AVRC_BldCommand"));
357 
358   ASSERT_EQ(std::future_status::ready,
359             g_btrc_connection_state_future.wait_for(std::chrono::seconds(3)));
360   auto res = g_btrc_connection_state_future.get();
361   ASSERT_TRUE(res.rc_state);
362 }
363 
TEST_F(BtifRcConnectionTest,bt_av_rc_open_evt)364 TEST_F(BtifRcConnectionTest, bt_av_rc_open_evt) {
365   btrc_ctrl_callbacks.get_cover_art_psm_cb = [](const RawAddress& /* bd_addr */,
366                                                 const uint16_t /* psm */) {};
367   btrc_ctrl_callbacks.getrcfeatures_cb = [](const RawAddress& /* bd_addr */, int /* features */) {};
368 
369   /* handle_rc_connect  */
370   tBTA_AV data = {
371           .rc_open =
372                   {
373                           .rc_handle = 0,
374                           .cover_art_psm = 0,
375                           .peer_features = 0,
376                           .peer_ct_features = 0,
377                           .peer_tg_features = (BTA_AV_FEAT_METADATA | BTA_AV_FEAT_VENDOR |
378                                                BTA_AV_FEAT_RCTG | BTA_AV_FEAT_RCCT),
379                           .peer_addr = kDeviceAddress,
380                           .status = BTA_AV_SUCCESS,
381                   },
382   };
383   btif_rc_cb.rc_multi_cb[0].rc_handle = 0;
384   btif_rc_cb.rc_multi_cb[0].rc_addr = RawAddress::kEmpty;
385   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_DISCONNECTED;
386   btif_rc_cb.rc_multi_cb[0].rc_connected = false;
387 
388   btif_rc_handler(BTA_AV_RC_OPEN_EVT, &data);
389 
390   ASSERT_TRUE(btif_rc_cb.rc_multi_cb[data.rc_open.rc_handle].rc_connected);
391   ASSERT_EQ(btif_rc_cb.rc_multi_cb[data.rc_open.rc_handle].rc_state,
392             BTRC_CONNECTION_STATE_CONNECTED);
393 
394   ASSERT_EQ(std::future_status::ready,
395             g_btrc_connection_state_future.wait_for(std::chrono::seconds(2)));
396   auto res = g_btrc_connection_state_future.get();
397   ASSERT_TRUE(res.rc_state);
398 }
399 
400 class BtifTrackChangeCBTest : public BtifRcTest {
401 protected:
SetUp()402   void SetUp() override {
403     BtifRcTest::SetUp();
404     init_ctrl(&btrc_ctrl_callbacks);
405     jni_thread.StartUp();
406     btrc_ctrl_callbacks.track_changed_cb = [](const RawAddress& bd_addr, uint8_t /*num_attr*/,
407                                               btrc_element_attr_val_t* /*p_attrs*/) {
408       btif_rc_cb.rc_multi_cb[0].rc_addr = bd_addr;
409     };
410   }
411 
TearDown()412   void TearDown() override {
413     jni_thread.ShutDown();
414     btrc_ctrl_callbacks.track_changed_cb = [](const RawAddress& /*bd_addr*/, uint8_t /*num_attr*/,
415                                               btrc_element_attr_val_t* /*p_attrs*/) {};
416     BtifRcTest::TearDown();
417   }
418 };
419 
TEST_F(BtifTrackChangeCBTest,handle_get_metadata_attr_response)420 TEST_F(BtifTrackChangeCBTest, handle_get_metadata_attr_response) {
421   // Setup an already connected device
422   btif_rc_cb.rc_multi_cb[0].rc_connected = true;
423   btif_rc_cb.rc_multi_cb[0].br_connected = false;
424   btif_rc_cb.rc_multi_cb[0].rc_handle = kRcHandle;
425   btif_rc_cb.rc_multi_cb[0].rc_features = {};
426   btif_rc_cb.rc_multi_cb[0].rc_cover_art_psm = 0;
427   btif_rc_cb.rc_multi_cb[0].rc_state = BTRC_CONNECTION_STATE_CONNECTED;
428   btif_rc_cb.rc_multi_cb[0].rc_addr = kDeviceAddress;
429   btif_rc_cb.rc_multi_cb[0].rc_pending_play = 0;
430   btif_rc_cb.rc_multi_cb[0].rc_volume = 0;
431   btif_rc_cb.rc_multi_cb[0].rc_vol_label = 0;
432   btif_rc_cb.rc_multi_cb[0].rc_supported_event_list = nullptr;
433   btif_rc_cb.rc_multi_cb[0].rc_app_settings = {};
434   btif_rc_cb.rc_multi_cb[0].rc_play_status_timer = nullptr;
435   btif_rc_cb.rc_multi_cb[0].rc_features_processed = false;
436   btif_rc_cb.rc_multi_cb[0].rc_playing_uid = 0;
437   btif_rc_cb.rc_multi_cb[0].rc_procedure_complete = false;
438   btif_rc_cb.rc_multi_cb[0].peer_ct_features = {};
439   btif_rc_cb.rc_multi_cb[0].peer_tg_features = {};
440   btif_rc_cb.rc_multi_cb[0].launch_cmd_pending = 0;
441   ASSERT_TRUE(btif_rc_get_device_by_handle(kRcHandle));
442 
443   tBTA_AV_META_MSG meta_msg = {
444           .rc_handle = kRcHandle,
445           .len = 0,
446           .label = 0,
447           .code{},
448           .company_id = 0,
449           .p_data = {},
450           .p_msg = nullptr,
451   };
452 
453   tAVRC_GET_ATTRS_RSP rsp = {
454           .pdu = 0,
455           .status = AVRC_STS_NO_ERROR,
456           .opcode = 0,
457           .num_attrs = 0,
458           .p_attrs = nullptr,
459   };
460 
461   handle_get_metadata_attr_response(&meta_msg, &rsp);
462 
463   ASSERT_EQ(1, get_func_call_count("osi_free_and_reset"));
464 }
465