• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 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 #include "btif/include/btif_dm.h"
18 
19 #include <com_android_bluetooth_flags.h>
20 #include <flag_macros.h>
21 #include <gtest/gtest.h>
22 
23 #include <memory>
24 
25 #include "bta/include/bta_api_data_types.h"
26 #include "btif/include/mock_core_callbacks.h"
27 #include "btif/include/stack_manager_t.h"
28 #include "main/shim/entry.h"
29 #include "main/shim/shim.h"
30 #include "main/shim/stack.h"
31 #include "module.h"
32 #include "stack/include/bt_dev_class.h"
33 #include "stack/include/btm_ble_api_types.h"
34 #include "storage/storage_module.h"
35 #include "test/fake/fake_osi.h"
36 #include "test/mock/mock_osi_properties.h"
37 
38 using bluetooth::core::testing::MockCoreInterface;
39 using ::testing::ElementsAre;
40 
41 namespace {
42 const RawAddress kRawAddress = {{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}};
43 constexpr char kBdName[] = {'k', 'B', 'd', 'N', 'a', 'm', 'e', '\0'};
44 }  // namespace
45 
46 namespace {
47 constexpr tBTM_BLE_TX_TIME_MS tx_time = 0x12345678;
48 constexpr tBTM_BLE_RX_TIME_MS rx_time = 0x87654321;
49 constexpr tBTM_BLE_IDLE_TIME_MS idle_time = 0x2468acd0;
50 constexpr tBTM_BLE_ENERGY_USED energy_used = 0x13579bdf;
51 }  // namespace
52 
53 class BtifDmWithMocksTest : public ::testing::Test {
54 protected:
SetUp()55   void SetUp() override { fake_osi_ = std::make_unique<test::fake::FakeOsi>(); }
56 
TearDown()57   void TearDown() override { fake_osi_.reset(); }
58 
59   std::unique_ptr<test::fake::FakeOsi> fake_osi_;
60 };
61 
62 class BtifDmTest : public BtifDmWithMocksTest {
63 protected:
SetUp()64   void SetUp() override {
65     BtifDmWithMocksTest::SetUp();
66     mock_core_interface_ = std::make_unique<MockCoreInterface>();
67     bluetooth::legacy::testing::set_interface_to_profiles(mock_core_interface_.get());
68   }
69 
TearDown()70   void TearDown() override {
71     bluetooth::legacy::testing::set_interface_to_profiles(nullptr);
72     mock_core_interface_.reset();
73     BtifDmWithMocksTest::TearDown();
74   }
75 
76   std::unique_ptr<MockCoreInterface> mock_core_interface_;
77 };
78 
TEST_F(BtifDmTest,bta_energy_info_cb__with_no_uid)79 TEST_F(BtifDmTest, bta_energy_info_cb__with_no_uid) {
80   static bool invoke_energy_info_cb_entered = false;
81   bluetooth::core::testing::mock_event_callbacks.invoke_energy_info_cb =
82           [](bt_activity_energy_info /* energy_info */, bt_uid_traffic_t* /* uid_data */) {
83             invoke_energy_info_cb_entered = true;
84           };
85 
86   bluetooth::legacy::testing::bta_energy_info_cb(tx_time, rx_time, idle_time, energy_used,
87                                                  BTM_CONTRL_UNKNOWN, BTA_SUCCESS);
88 
89   ASSERT_FALSE(invoke_energy_info_cb_entered);
90 }
91 
92 class BtifDmWithUidTest : public BtifDmTest {
93 protected:
SetUp()94   void SetUp() override {
95     BtifDmTest::SetUp();
96     btif_dm_init(uid_set_create());
97   }
98 
TearDown()99   void TearDown() override {
100     btif_dm_cleanup();
101     BtifDmTest::TearDown();
102   }
103 };
104 
TEST_F(BtifDmWithUidTest,bta_energy_info_cb__with_uid)105 TEST_F(BtifDmWithUidTest, bta_energy_info_cb__with_uid) {
106   static bool invoke_energy_info_cb_entered = false;
107   bluetooth::core::testing::mock_event_callbacks.invoke_energy_info_cb =
108           [](bt_activity_energy_info /* energy_info */, bt_uid_traffic_t* /* uid_data */) {
109             invoke_energy_info_cb_entered = true;
110           };
111   bluetooth::legacy::testing::bta_energy_info_cb(tx_time, rx_time, idle_time, energy_used,
112                                                  BTM_CONTRL_UNKNOWN, BTA_SUCCESS);
113 
114   ASSERT_TRUE(invoke_energy_info_cb_entered);
115 }
116 
117 // Mock implementation for GetStorage()
118 static bluetooth::storage::StorageModule* s_StorageModule = nullptr;
GetStorage()119 bluetooth::storage::StorageModule* bluetooth::shim::GetStorage() { return s_StorageModule; }
120 
GetGdShimHandler()121 bluetooth::os::Handler* bluetooth::shim::GetGdShimHandler() { return nullptr; }
GetAdvertising()122 bluetooth::hci::LeAdvertisingManager* bluetooth::shim::GetAdvertising() { return nullptr; }
GetController()123 bluetooth::hci::ControllerInterface* bluetooth::shim::GetController() { return nullptr; }
GetHciLayer()124 bluetooth::hci::HciInterface* bluetooth::shim::GetHciLayer() { return nullptr; }
GetRemoteNameRequest()125 bluetooth::hci::RemoteNameRequestModule* bluetooth::shim::GetRemoteNameRequest() { return nullptr; }
GetScanning()126 bluetooth::hci::LeScanningManager* bluetooth::shim::GetScanning() { return nullptr; }
GetDistanceMeasurementManager()127 bluetooth::hci::DistanceMeasurementManager* bluetooth::shim::GetDistanceMeasurementManager() {
128   return nullptr;
129 }
GetSnoopLogger()130 bluetooth::hal::SnoopLogger* bluetooth::shim::GetSnoopLogger() { return nullptr; }
GetLppOffloadManager()131 bluetooth::lpp::LppOffloadInterface* bluetooth::shim::GetLppOffloadManager() { return nullptr; }
GetAclManager()132 bluetooth::hci::AclManager* bluetooth::shim::GetAclManager() { return nullptr; }
GetCounterMetrics()133 bluetooth::metrics::CounterMetrics* bluetooth::shim::GetCounterMetrics() { return nullptr; }
GetMsftExtensionManager()134 bluetooth::hci::MsftExtensionManager* bluetooth::shim::GetMsftExtensionManager() { return nullptr; }
135 
is_gd_stack_started_up()136 bool bluetooth::shim::is_gd_stack_started_up() { return s_StorageModule != nullptr; }
137 
138 class BtifDmWithStackTest : public BtifDmTest {
139 protected:
SetUp()140   void SetUp() override {
141     BtifDmTest::SetUp();
142     thread_ = new bluetooth::os::Thread("gd_stack_thread", bluetooth::os::Thread::Priority::NORMAL);
143     storage_module_ = new bluetooth::storage::StorageModule(new bluetooth::os::Handler(thread_));
144     storage_module_->Start();
145     s_StorageModule = storage_module_;
146   }
147 
TearDown()148   void TearDown() override {
149     storage_module_->Stop();
150     s_StorageModule = nullptr;
151     delete storage_module_;
152     delete thread_;
153     BtifDmTest::TearDown();
154   }
155 
156   bluetooth::os::Thread* thread_;
157   bluetooth::storage::StorageModule* storage_module_;
158 };
159 
TEST_F_WITH_FLAGS(BtifDmWithStackTest,btif_dm_search_services_evt__BTA_DM_NAME_READ_EVT)160 TEST_F_WITH_FLAGS(BtifDmWithStackTest, btif_dm_search_services_evt__BTA_DM_NAME_READ_EVT) {
161   static struct {
162     bt_status_t status;
163     RawAddress bd_addr;
164     int num_properties;
165     std::vector<bt_property_t> properties;
166   } invoke_remote_device_properties_cb{
167           .status = BT_STATUS_NOT_READY,
168           .bd_addr = RawAddress::kEmpty,
169           .num_properties = -1,
170           .properties = {},
171   };
172 
173   bluetooth::core::testing::mock_event_callbacks.invoke_remote_device_properties_cb =
174           [](bt_status_t status, RawAddress bd_addr, int num_properties,
175              bt_property_t* properties) {
176             invoke_remote_device_properties_cb = {
177                     .status = status,
178                     .bd_addr = bd_addr,
179                     .num_properties = num_properties,
180                     .properties = std::vector<bt_property_t>(properties,
181                                                              properties + (size_t)num_properties),
182             };
183           };
184 
185   BD_NAME bd_name;
186   bd_name_from_char_pointer(bd_name, kBdName);
187 
188   bluetooth::legacy::testing::btif_on_name_read(kRawAddress, HCI_SUCCESS, bd_name, true);
189 
190   ASSERT_EQ(BT_STATUS_SUCCESS, invoke_remote_device_properties_cb.status);
191   ASSERT_EQ(kRawAddress, invoke_remote_device_properties_cb.bd_addr);
192   ASSERT_EQ(1, invoke_remote_device_properties_cb.num_properties);
193   ASSERT_EQ(BT_PROPERTY_BDNAME, invoke_remote_device_properties_cb.properties[0].type);
194   ASSERT_EQ((int)strlen(kBdName), invoke_remote_device_properties_cb.properties[0].len);
195   ASSERT_STREQ(kBdName, (const char*)invoke_remote_device_properties_cb.properties[0].val);
196 }
197 
TEST_F(BtifDmWithStackTest,btif_dm_get_local_class_of_device__default)198 TEST_F(BtifDmWithStackTest, btif_dm_get_local_class_of_device__default) {
199   DEV_CLASS dev_class = btif_dm_get_local_class_of_device();
200   ASSERT_EQ(dev_class, kDevClassUnclassified);
201 }
202 
203 std::string kClassOfDeviceText = "1,2,3";
204 DEV_CLASS kClassOfDevice = {1, 2, 3};
TEST_F(BtifDmWithStackTest,btif_dm_get_local_class_of_device__with_property)205 TEST_F(BtifDmWithStackTest, btif_dm_get_local_class_of_device__with_property) {
206   test::mock::osi_properties::osi_property_get.body = [](const char* /* key */, char* value,
207                                                          const char* /* default_value */) {
208     std::copy(kClassOfDeviceText.begin(), kClassOfDeviceText.end(), value);
209     return kClassOfDeviceText.size();
210   };
211 
212   DEV_CLASS dev_class = btif_dm_get_local_class_of_device();
213   if (dev_class != kClassOfDevice) {
214     // If BAP is enabled, an extra bit gets set.
215     DEV_CLASS dev_class_with_bap = kClassOfDevice;
216     dev_class_with_bap[1] |= 0x01 << 6;
217     ASSERT_EQ(dev_class, dev_class_with_bap);
218   }
219   test::mock::osi_properties::osi_property_get = {};
220 }
221