• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 HIMSA II K/S - www.himsa.com.
3  * Represented by EHIMA - www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 #include "bta_groups.h"
22 #include "gd/os/rand.h"
23 #include "test/common/mock_functions.h"
24 #include "types/bluetooth/uuid.h"
25 #include "types/raw_address.h"
26 
27 namespace bluetooth {
28 namespace groups {
29 
30 using ::testing::_;
31 using ::testing::DoAll;
32 using ::testing::Invoke;
33 using ::testing::Mock;
34 using ::testing::Return;
35 using ::testing::SaveArg;
36 using ::testing::SetArgPointee;
37 using ::testing::Test;
38 
39 using bluetooth::groups::DeviceGroups;
40 using bluetooth::groups::DeviceGroupsCallbacks;
41 
42 DeviceGroupsCallbacks* dev_callbacks;
43 
GetTestAddress(int index)44 RawAddress GetTestAddress(int index) {
45   EXPECT_LT(index, UINT8_MAX);
46   RawAddress result = {
47       {0xC0, 0xDE, 0xC0, 0xDE, 0x00, static_cast<uint8_t>(index)}};
48   return result;
49 }
50 
51 class MockGroupsCallbacks : public DeviceGroupsCallbacks {
52  public:
53   MockGroupsCallbacks() = default;
54   MockGroupsCallbacks(const MockGroupsCallbacks&) = delete;
55   MockGroupsCallbacks& operator=(const MockGroupsCallbacks&) = delete;
56 
57   ~MockGroupsCallbacks() override = default;
58 
59   MOCK_METHOD((void), OnGroupAdded,
60               (const RawAddress& address, const bluetooth::Uuid& uuid,
61                int group_id),
62               (override));
63   MOCK_METHOD((void), OnGroupMemberAdded,
64               (const RawAddress& address, int group_id), (override));
65 
66   MOCK_METHOD((void), OnGroupRemoved,
67               (const bluetooth::Uuid& uuid, int group_id), (override));
68   MOCK_METHOD((void), OnGroupMemberRemoved,
69               (const RawAddress& address, int group_id), (override));
70   MOCK_METHOD((void), OnGroupAddFromStorage,
71               (const RawAddress& address, const bluetooth::Uuid& uuid,
72                int group_id),
73               (override));
74 };
75 
76 class GroupsTest : public ::testing::Test {
77  protected:
SetUp()78   void SetUp() override {
79     reset_mock_function_count_map();
80     callbacks.reset(new MockGroupsCallbacks());
81   }
82 
TearDown()83   void TearDown() override { DeviceGroups::CleanUp(callbacks.get()); }
84 
85   std::unique_ptr<MockGroupsCallbacks> callbacks;
86 };
87 
TEST_F(GroupsTest,test_initialize)88 TEST_F(GroupsTest, test_initialize) {
89   DeviceGroups::Initialize(callbacks.get());
90   ASSERT_TRUE(DeviceGroups::Get());
91   DeviceGroups::CleanUp(callbacks.get());
92 }
93 
TEST_F(GroupsTest,test_initialize_twice)94 TEST_F(GroupsTest, test_initialize_twice) {
95   DeviceGroups::Initialize(callbacks.get());
96   DeviceGroups* dev_groups_p = DeviceGroups::Get();
97   DeviceGroups::Initialize(callbacks.get());
98   ASSERT_EQ(dev_groups_p, DeviceGroups::Get());
99   DeviceGroups::CleanUp(callbacks.get());
100   dev_groups_p->CleanUp(callbacks.get());
101 }
102 
TEST_F(GroupsTest,test_cleanup_initialized)103 TEST_F(GroupsTest, test_cleanup_initialized) {
104   DeviceGroups::Initialize(callbacks.get());
105   DeviceGroups::CleanUp(callbacks.get());
106   ASSERT_FALSE(DeviceGroups::Get());
107 }
108 
TEST_F(GroupsTest,test_cleanup_uninitialized)109 TEST_F(GroupsTest, test_cleanup_uninitialized) {
110   DeviceGroups::CleanUp(callbacks.get());
111   ASSERT_FALSE(DeviceGroups::Get());
112 }
113 
TEST_F(GroupsTest,test_groups_add_single_device)114 TEST_F(GroupsTest, test_groups_add_single_device) {
115   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(1), Uuid::kEmpty, 7));
116   DeviceGroups::Initialize(callbacks.get());
117   DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 7);
118   DeviceGroups::CleanUp(callbacks.get());
119 }
120 
TEST_F(GroupsTest,test_groups_add_two_devices)121 TEST_F(GroupsTest, test_groups_add_two_devices) {
122   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(1), _, 7));
123   EXPECT_CALL(*callbacks, OnGroupMemberAdded(GetTestAddress(2), 7));
124   DeviceGroups::Initialize(callbacks.get());
125   DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 7);
126   DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
127   DeviceGroups::CleanUp(callbacks.get());
128 }
129 
TEST_F(GroupsTest,test_groups_remove_device)130 TEST_F(GroupsTest, test_groups_remove_device) {
131   EXPECT_CALL(*callbacks, OnGroupMemberRemoved(GetTestAddress(2), 7));
132   DeviceGroups::Initialize(callbacks.get());
133   DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
134   DeviceGroups::Get()->RemoveDevice(GetTestAddress(2));
135   ASSERT_EQ(kGroupUnknown,
136             DeviceGroups::Get()->GetGroupId(GetTestAddress(2), Uuid::kEmpty));
137   ASSERT_EQ(kGroupUnknown,
138             DeviceGroups::Get()->GetGroupId(GetTestAddress(3), Uuid::kEmpty));
139   DeviceGroups::CleanUp(callbacks.get());
140 }
141 
TEST_F(GroupsTest,test_add_multiple_devices)142 TEST_F(GroupsTest, test_add_multiple_devices) {
143   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(2), Uuid::kEmpty, 7));
144   EXPECT_CALL(*callbacks, OnGroupMemberAdded(_, 7)).Times(2);
145   DeviceGroups::Initialize(callbacks.get());
146   DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
147   DeviceGroups::Get()->AddDevice(GetTestAddress(3), Uuid::kEmpty, 7);
148   DeviceGroups::Get()->AddDevice(GetTestAddress(4), Uuid::kEmpty, 7);
149   DeviceGroups::CleanUp(callbacks.get());
150 }
151 
TEST_F(GroupsTest,test_remove_multiple_devices)152 TEST_F(GroupsTest, test_remove_multiple_devices) {
153   EXPECT_CALL(*callbacks, OnGroupMemberRemoved(_, _)).Times(3);
154   DeviceGroups::Initialize(callbacks.get());
155   DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
156   DeviceGroups::Get()->AddDevice(GetTestAddress(3), Uuid::kEmpty, 7);
157   DeviceGroups::Get()->AddDevice(GetTestAddress(4), Uuid::kEmpty, 7);
158   DeviceGroups::Get()->RemoveDevice(GetTestAddress(2));
159   DeviceGroups::Get()->RemoveDevice(GetTestAddress(3));
160   DeviceGroups::Get()->RemoveDevice(GetTestAddress(4));
161   DeviceGroups::CleanUp(callbacks.get());
162 }
163 
TEST_F(GroupsTest,test_add_multiple_groups)164 TEST_F(GroupsTest, test_add_multiple_groups) {
165   EXPECT_CALL(*callbacks, OnGroupAdded(_, _, _)).Times(2);
166   DeviceGroups::Initialize(callbacks.get());
167   DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 8);
168   DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 9);
169   DeviceGroups::CleanUp(callbacks.get());
170 }
171 
TEST_F(GroupsTest,test_remove_multiple_groups)172 TEST_F(GroupsTest, test_remove_multiple_groups) {
173   Uuid uuid1 =
174       Uuid::From128BitBE(bluetooth::os::GenerateRandom<Uuid::kNumBytes128>());
175   Uuid uuid2 =
176       Uuid::From128BitBE(bluetooth::os::GenerateRandom<Uuid::kNumBytes128>());
177   ASSERT_NE(uuid1, uuid2);
178 
179   EXPECT_CALL(*callbacks, OnGroupAdded(_, _, _)).Times(2);
180   DeviceGroups::Initialize(callbacks.get());
181   DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid1, 8);
182   DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid2, 9);
183   DeviceGroups::Get()->AddDevice(GetTestAddress(2), uuid2, 9);
184 
185   EXPECT_CALL(*callbacks, OnGroupMemberRemoved(GetTestAddress(1), 8));
186   EXPECT_CALL(*callbacks, OnGroupMemberRemoved(GetTestAddress(1), 9));
187   EXPECT_CALL(*callbacks, OnGroupRemoved(uuid1, 8));
188   EXPECT_CALL(*callbacks, OnGroupRemoved(uuid2, 9)).Times(0);
189   DeviceGroups::Get()->RemoveDevice(GetTestAddress(1));
190 
191   DeviceGroups::CleanUp(callbacks.get());
192 }
193 
TEST_F(GroupsTest,test_remove_device_fo_devices)194 TEST_F(GroupsTest, test_remove_device_fo_devices) {
195   Uuid uuid1 =
196       Uuid::From128BitBE(bluetooth::os::GenerateRandom<Uuid::kNumBytes128>());
197   Uuid uuid2 =
198       Uuid::From128BitBE(bluetooth::os::GenerateRandom<Uuid::kNumBytes128>());
199   EXPECT_CALL(*callbacks, OnGroupAdded(_, _, _)).Times(2);
200   DeviceGroups::Initialize(callbacks.get());
201   DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid1, 8);
202   DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid2, 9);
203 
204   EXPECT_CALL(*callbacks, OnGroupRemoved(uuid1, 8));
205   EXPECT_CALL(*callbacks, OnGroupRemoved(uuid2, 9)).Times(0);
206 
207   DeviceGroups::Get()->RemoveDevice(GetTestAddress(1), 8);
208 
209   Mock::VerifyAndClearExpectations(&callbacks);
210 
211   EXPECT_CALL(*callbacks, OnGroupRemoved(uuid1, 8)).Times(0);
212   EXPECT_CALL(*callbacks, OnGroupRemoved(uuid2, 9));
213 
214   DeviceGroups::Get()->RemoveDevice(GetTestAddress(1), 9);
215 }
216 
TEST_F(GroupsTest,test_add_devices_different_group_id)217 TEST_F(GroupsTest, test_add_devices_different_group_id) {
218   DeviceGroups::Initialize(callbacks.get());
219   DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 10);
220   DeviceGroups::Get()->AddDevice(GetTestAddress(3), Uuid::kEmpty, 11);
221   auto group_id_1 =
222       DeviceGroups::Get()->GetGroupId(GetTestAddress(2), Uuid::kEmpty);
223   auto group_id_2 =
224       DeviceGroups::Get()->GetGroupId(GetTestAddress(3), Uuid::kEmpty);
225   ASSERT_TRUE(group_id_1 != group_id_2);
226   DeviceGroups::CleanUp(callbacks.get());
227 }
228 
TEST_F(GroupsTest,test_group_id_assign)229 TEST_F(GroupsTest, test_group_id_assign) {
230   int captured_gid1 = kGroupUnknown;
231   int captured_gid2 = kGroupUnknown;
232 
233   DeviceGroups::Initialize(callbacks.get());
234   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(1), _, _))
235       .WillOnce(SaveArg<2>(&captured_gid1));
236   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(2), _, _))
237       .WillOnce(SaveArg<2>(&captured_gid2));
238 
239   int gid1 = DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty,
240                                             bluetooth::groups::kGroupUnknown);
241   int gid2 = DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty);
242   int gid3 = DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty);
243   ASSERT_NE(bluetooth::groups::kGroupUnknown, gid1);
244   ASSERT_NE(bluetooth::groups::kGroupUnknown, gid2);
245   ASSERT_EQ(gid2, gid3);
246   ASSERT_EQ(gid1, captured_gid1);
247   ASSERT_EQ(gid2, captured_gid2);
248 
249   DeviceGroups::CleanUp(callbacks.get());
250 }
251 
TEST_F(GroupsTest,test_storage_calls)252 TEST_F(GroupsTest, test_storage_calls) {
253   ASSERT_EQ(0, get_func_call_count("btif_storage_load_bonded_groups"));
254   DeviceGroups::Initialize(callbacks.get());
255   ASSERT_EQ(1, get_func_call_count("btif_storage_load_bonded_groups"));
256 
257   ASSERT_EQ(0, get_func_call_count("btif_storage_add_groups"));
258   DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 7);
259   DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 8);
260   ASSERT_EQ(2, get_func_call_count("btif_storage_add_groups"));
261 
262   DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
263   DeviceGroups::Get()->AddDevice(GetTestAddress(3), Uuid::kEmpty, 7);
264   ASSERT_EQ(4, get_func_call_count("btif_storage_add_groups"));
265 
266   ASSERT_EQ(0, get_func_call_count("btif_storage_remove_groups"));
267   DeviceGroups::Get()->RemoveDevice(GetTestAddress(1));
268   DeviceGroups::Get()->RemoveDevice(GetTestAddress(2));
269   DeviceGroups::Get()->RemoveDevice(GetTestAddress(3));
270   ASSERT_EQ(3, get_func_call_count("btif_storage_remove_groups"));
271 
272   DeviceGroups::CleanUp(callbacks.get());
273 }
274 
TEST_F(GroupsTest,test_storage_content)275 TEST_F(GroupsTest, test_storage_content) {
276   int gid1 = bluetooth::groups::kGroupUnknown;
277   int gid2 = bluetooth::groups::kGroupUnknown;
278   Uuid uuid1 =
279       Uuid::From128BitBE(bluetooth::os::GenerateRandom<Uuid::kNumBytes128>());
280   Uuid uuid2 =
281       Uuid::From128BitBE(bluetooth::os::GenerateRandom<Uuid::kNumBytes128>());
282   ASSERT_NE(uuid1, uuid2);
283 
284   DeviceGroups::Initialize(callbacks.get());
285   gid1 = DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid1, gid1);
286   DeviceGroups::Get()->AddDevice(GetTestAddress(2), uuid1, gid1);
287   gid2 = DeviceGroups::Get()->AddDevice(GetTestAddress(2), uuid2, gid2);
288   ASSERT_NE(bluetooth::groups::kGroupUnknown, gid1);
289   ASSERT_NE(gid1, gid2);
290 
291   std::vector<uint8_t> dev1_storage;
292   std::vector<uint8_t> dev2_storage;
293 
294   // Store to byte buffer
295   DeviceGroups::GetForStorage(GetTestAddress(1), dev1_storage);
296   DeviceGroups::GetForStorage(GetTestAddress(2), dev2_storage);
297   ASSERT_NE(0u, dev1_storage.size());
298   ASSERT_TRUE(dev2_storage.size() > dev1_storage.size());
299 
300   // Clean it up
301   DeviceGroups::CleanUp(callbacks.get());
302   ASSERT_EQ(nullptr, DeviceGroups::Get());
303 
304   // Restore dev1 from the byte buffer
305   DeviceGroups::Initialize(callbacks.get());
306   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(1), uuid1, gid1));
307   DeviceGroups::AddFromStorage(GetTestAddress(1), dev1_storage);
308 
309   // Restore dev2 from the byte buffer
310   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(2), uuid2, gid2));
311   EXPECT_CALL(*callbacks, OnGroupMemberAdded(GetTestAddress(2), gid1)).Times(1);
312   DeviceGroups::AddFromStorage(GetTestAddress(2), dev2_storage);
313 
314   DeviceGroups::CleanUp(callbacks.get());
315 }
316 
317 }  // namespace groups
318 }  // namespace bluetooth
319