• 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 <base/logging.h>
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 
22 #include "bta_groups.h"
23 #include "types/bluetooth/uuid.h"
24 #include "types/raw_address.h"
25 
26 std::map<std::string, int> mock_function_count_map;
27 
28 namespace bluetooth {
29 namespace groups {
30 
31 using ::testing::_;
32 using ::testing::DoAll;
33 using ::testing::Invoke;
34 using ::testing::Mock;
35 using ::testing::Return;
36 using ::testing::SaveArg;
37 using ::testing::SetArgPointee;
38 using ::testing::Test;
39 
40 using bluetooth::groups::DeviceGroups;
41 using bluetooth::groups::DeviceGroupsCallbacks;
42 
43 DeviceGroupsCallbacks* dev_callbacks;
44 
GetTestAddress(int index)45 RawAddress GetTestAddress(int index) {
46   CHECK_LT(index, UINT8_MAX);
47   RawAddress result = {
48       {0xC0, 0xDE, 0xC0, 0xDE, 0x00, static_cast<uint8_t>(index)}};
49   return result;
50 }
51 
52 class MockGroupsCallbacks : public DeviceGroupsCallbacks {
53  public:
54   MockGroupsCallbacks() = default;
55   MockGroupsCallbacks(const MockGroupsCallbacks&) = delete;
56   MockGroupsCallbacks& operator=(const MockGroupsCallbacks&) = delete;
57 
58   ~MockGroupsCallbacks() override = default;
59 
60   MOCK_METHOD((void), OnGroupAdded,
61               (const RawAddress& address, const bluetooth::Uuid& uuid,
62                int group_id),
63               (override));
64   MOCK_METHOD((void), OnGroupMemberAdded,
65               (const RawAddress& address, int group_id), (override));
66 
67   MOCK_METHOD((void), OnGroupRemoved,
68               (const bluetooth::Uuid& uuid, int group_id), (override));
69   MOCK_METHOD((void), OnGroupMemberRemoved,
70               (const RawAddress& address, int group_id), (override));
71   MOCK_METHOD((void), OnGroupAddFromStorage,
72               (const RawAddress& address, const bluetooth::Uuid& uuid,
73                int group_id),
74               (override));
75 };
76 
77 class GroupsTest : public ::testing::Test {
78  protected:
SetUp()79   void SetUp() override {
80     mock_function_count_map.clear();
81     callbacks.reset(new MockGroupsCallbacks());
82   }
83 
TearDown()84   void TearDown() override { DeviceGroups::CleanUp(callbacks.get()); }
85 
86   std::unique_ptr<MockGroupsCallbacks> callbacks;
87 };
88 
TEST_F(GroupsTest,test_initialize)89 TEST_F(GroupsTest, test_initialize) {
90   DeviceGroups::Initialize(callbacks.get());
91   ASSERT_TRUE(DeviceGroups::Get());
92   DeviceGroups::CleanUp(callbacks.get());
93 }
94 
TEST_F(GroupsTest,test_initialize_twice)95 TEST_F(GroupsTest, test_initialize_twice) {
96   DeviceGroups::Initialize(callbacks.get());
97   DeviceGroups* dev_groups_p = DeviceGroups::Get();
98   DeviceGroups::Initialize(callbacks.get());
99   ASSERT_EQ(dev_groups_p, DeviceGroups::Get());
100   DeviceGroups::CleanUp(callbacks.get());
101   dev_groups_p->CleanUp(callbacks.get());
102 }
103 
TEST_F(GroupsTest,test_cleanup_initialized)104 TEST_F(GroupsTest, test_cleanup_initialized) {
105   DeviceGroups::Initialize(callbacks.get());
106   DeviceGroups::CleanUp(callbacks.get());
107   ASSERT_FALSE(DeviceGroups::Get());
108 }
109 
TEST_F(GroupsTest,test_cleanup_uninitialized)110 TEST_F(GroupsTest, test_cleanup_uninitialized) {
111   DeviceGroups::CleanUp(callbacks.get());
112   ASSERT_FALSE(DeviceGroups::Get());
113 }
114 
TEST_F(GroupsTest,test_groups_add_single_device)115 TEST_F(GroupsTest, test_groups_add_single_device) {
116   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(1), Uuid::kEmpty, 7));
117   DeviceGroups::Initialize(callbacks.get());
118   DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 7);
119   DeviceGroups::CleanUp(callbacks.get());
120 }
121 
TEST_F(GroupsTest,test_groups_add_two_devices)122 TEST_F(GroupsTest, test_groups_add_two_devices) {
123   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(1), _, 7));
124   EXPECT_CALL(*callbacks, OnGroupMemberAdded(GetTestAddress(2), 7));
125   DeviceGroups::Initialize(callbacks.get());
126   DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 7);
127   DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
128   DeviceGroups::CleanUp(callbacks.get());
129 }
130 
TEST_F(GroupsTest,test_groups_remove_device)131 TEST_F(GroupsTest, test_groups_remove_device) {
132   EXPECT_CALL(*callbacks, OnGroupMemberRemoved(GetTestAddress(2), 7));
133   DeviceGroups::Initialize(callbacks.get());
134   DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
135   DeviceGroups::Get()->RemoveDevice(GetTestAddress(2));
136   ASSERT_EQ(kGroupUnknown,
137             DeviceGroups::Get()->GetGroupId(GetTestAddress(2), Uuid::kEmpty));
138   ASSERT_EQ(kGroupUnknown,
139             DeviceGroups::Get()->GetGroupId(GetTestAddress(3), Uuid::kEmpty));
140   DeviceGroups::CleanUp(callbacks.get());
141 }
142 
TEST_F(GroupsTest,test_add_multiple_devices)143 TEST_F(GroupsTest, test_add_multiple_devices) {
144   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(2), Uuid::kEmpty, 7));
145   EXPECT_CALL(*callbacks, OnGroupMemberAdded(_, 7)).Times(2);
146   DeviceGroups::Initialize(callbacks.get());
147   DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
148   DeviceGroups::Get()->AddDevice(GetTestAddress(3), Uuid::kEmpty, 7);
149   DeviceGroups::Get()->AddDevice(GetTestAddress(4), Uuid::kEmpty, 7);
150   DeviceGroups::CleanUp(callbacks.get());
151 }
152 
TEST_F(GroupsTest,test_remove_multiple_devices)153 TEST_F(GroupsTest, test_remove_multiple_devices) {
154   EXPECT_CALL(*callbacks, OnGroupMemberRemoved(_, _)).Times(3);
155   DeviceGroups::Initialize(callbacks.get());
156   DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
157   DeviceGroups::Get()->AddDevice(GetTestAddress(3), Uuid::kEmpty, 7);
158   DeviceGroups::Get()->AddDevice(GetTestAddress(4), Uuid::kEmpty, 7);
159   DeviceGroups::Get()->RemoveDevice(GetTestAddress(2));
160   DeviceGroups::Get()->RemoveDevice(GetTestAddress(3));
161   DeviceGroups::Get()->RemoveDevice(GetTestAddress(4));
162   DeviceGroups::CleanUp(callbacks.get());
163 }
164 
TEST_F(GroupsTest,test_add_multiple_groups)165 TEST_F(GroupsTest, test_add_multiple_groups) {
166   EXPECT_CALL(*callbacks, OnGroupAdded(_, _, _)).Times(2);
167   DeviceGroups::Initialize(callbacks.get());
168   DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 8);
169   DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 9);
170   DeviceGroups::CleanUp(callbacks.get());
171 }
172 
TEST_F(GroupsTest,test_remove_multiple_groups)173 TEST_F(GroupsTest, test_remove_multiple_groups) {
174   Uuid uuid1 = Uuid::GetRandom();
175   Uuid uuid2 = Uuid::GetRandom();
176   ASSERT_NE(uuid1, uuid2);
177 
178   EXPECT_CALL(*callbacks, OnGroupAdded(_, _, _)).Times(2);
179   DeviceGroups::Initialize(callbacks.get());
180   DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid1, 8);
181   DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid2, 9);
182   DeviceGroups::Get()->AddDevice(GetTestAddress(2), uuid2, 9);
183 
184   EXPECT_CALL(*callbacks, OnGroupMemberRemoved(GetTestAddress(1), 8));
185   EXPECT_CALL(*callbacks, OnGroupMemberRemoved(GetTestAddress(1), 9));
186   EXPECT_CALL(*callbacks, OnGroupRemoved(uuid1, 8));
187   EXPECT_CALL(*callbacks, OnGroupRemoved(uuid2, 9)).Times(0);
188   DeviceGroups::Get()->RemoveDevice(GetTestAddress(1));
189 
190   DeviceGroups::CleanUp(callbacks.get());
191 }
192 
TEST_F(GroupsTest,test_remove_device_fo_devices)193 TEST_F(GroupsTest, test_remove_device_fo_devices) {
194   Uuid uuid1 = Uuid::GetRandom();
195   Uuid uuid2 = Uuid::GetRandom();
196   EXPECT_CALL(*callbacks, OnGroupAdded(_, _, _)).Times(2);
197   DeviceGroups::Initialize(callbacks.get());
198   DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid1, 8);
199   DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid2, 9);
200 
201   EXPECT_CALL(*callbacks, OnGroupRemoved(uuid1, 8));
202   EXPECT_CALL(*callbacks, OnGroupRemoved(uuid2, 9)).Times(0);
203 
204   DeviceGroups::Get()->RemoveDevice(GetTestAddress(1), 8);
205 
206   Mock::VerifyAndClearExpectations(&callbacks);
207 
208   EXPECT_CALL(*callbacks, OnGroupRemoved(uuid1, 8)).Times(0);
209   EXPECT_CALL(*callbacks, OnGroupRemoved(uuid2, 9));
210 
211   DeviceGroups::Get()->RemoveDevice(GetTestAddress(1), 9);
212 }
213 
TEST_F(GroupsTest,test_add_devices_different_group_id)214 TEST_F(GroupsTest, test_add_devices_different_group_id) {
215   DeviceGroups::Initialize(callbacks.get());
216   DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 10);
217   DeviceGroups::Get()->AddDevice(GetTestAddress(3), Uuid::kEmpty, 11);
218   auto group_id_1 =
219       DeviceGroups::Get()->GetGroupId(GetTestAddress(2), Uuid::kEmpty);
220   auto group_id_2 =
221       DeviceGroups::Get()->GetGroupId(GetTestAddress(3), Uuid::kEmpty);
222   ASSERT_TRUE(group_id_1 != group_id_2);
223   DeviceGroups::CleanUp(callbacks.get());
224 }
225 
TEST_F(GroupsTest,test_group_id_assign)226 TEST_F(GroupsTest, test_group_id_assign) {
227   int captured_gid1 = kGroupUnknown;
228   int captured_gid2 = kGroupUnknown;
229 
230   DeviceGroups::Initialize(callbacks.get());
231   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(1), _, _))
232       .WillOnce(SaveArg<2>(&captured_gid1));
233   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(2), _, _))
234       .WillOnce(SaveArg<2>(&captured_gid2));
235 
236   int gid1 = DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty,
237                                             bluetooth::groups::kGroupUnknown);
238   int gid2 = DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty);
239   int gid3 = DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty);
240   ASSERT_NE(bluetooth::groups::kGroupUnknown, gid1);
241   ASSERT_NE(bluetooth::groups::kGroupUnknown, gid2);
242   ASSERT_EQ(gid2, gid3);
243   ASSERT_EQ(gid1, captured_gid1);
244   ASSERT_EQ(gid2, captured_gid2);
245 
246   DeviceGroups::CleanUp(callbacks.get());
247 }
248 
TEST_F(GroupsTest,test_storage_calls)249 TEST_F(GroupsTest, test_storage_calls) {
250   ASSERT_EQ(0, mock_function_count_map["btif_storage_load_bonded_groups"]);
251   DeviceGroups::Initialize(callbacks.get());
252   ASSERT_EQ(1, mock_function_count_map["btif_storage_load_bonded_groups"]);
253 
254   ASSERT_EQ(0, mock_function_count_map["btif_storage_add_groups"]);
255   DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 7);
256   DeviceGroups::Get()->AddDevice(GetTestAddress(1), Uuid::kEmpty, 8);
257   ASSERT_EQ(2, mock_function_count_map["btif_storage_add_groups"]);
258 
259   DeviceGroups::Get()->AddDevice(GetTestAddress(2), Uuid::kEmpty, 7);
260   DeviceGroups::Get()->AddDevice(GetTestAddress(3), Uuid::kEmpty, 7);
261   ASSERT_EQ(4, mock_function_count_map["btif_storage_add_groups"]);
262 
263   ASSERT_EQ(0, mock_function_count_map["btif_storage_remove_groups"]);
264   DeviceGroups::Get()->RemoveDevice(GetTestAddress(1));
265   DeviceGroups::Get()->RemoveDevice(GetTestAddress(2));
266   DeviceGroups::Get()->RemoveDevice(GetTestAddress(3));
267   ASSERT_EQ(3, mock_function_count_map["btif_storage_remove_groups"]);
268 
269   DeviceGroups::CleanUp(callbacks.get());
270 }
271 
TEST_F(GroupsTest,test_storage_content)272 TEST_F(GroupsTest, test_storage_content) {
273   int gid1 = bluetooth::groups::kGroupUnknown;
274   int gid2 = bluetooth::groups::kGroupUnknown;
275   Uuid uuid1 = Uuid::GetRandom();
276   Uuid uuid2 = Uuid::GetRandom();
277   ASSERT_NE(uuid1, uuid2);
278 
279   DeviceGroups::Initialize(callbacks.get());
280   gid1 = DeviceGroups::Get()->AddDevice(GetTestAddress(1), uuid1, gid1);
281   DeviceGroups::Get()->AddDevice(GetTestAddress(2), uuid1, gid1);
282   gid2 = DeviceGroups::Get()->AddDevice(GetTestAddress(2), uuid2, gid2);
283   ASSERT_NE(bluetooth::groups::kGroupUnknown, gid1);
284   ASSERT_NE(gid1, gid2);
285 
286   std::vector<uint8_t> dev1_storage;
287   std::vector<uint8_t> dev2_storage;
288 
289   // Store to byte buffer
290   DeviceGroups::GetForStorage(GetTestAddress(1), dev1_storage);
291   DeviceGroups::GetForStorage(GetTestAddress(2), dev2_storage);
292   ASSERT_NE(0u, dev1_storage.size());
293   ASSERT_TRUE(dev2_storage.size() > dev1_storage.size());
294 
295   // Clean it up
296   DeviceGroups::CleanUp(callbacks.get());
297   ASSERT_EQ(nullptr, DeviceGroups::Get());
298 
299   // Restore dev1 from the byte buffer
300   DeviceGroups::Initialize(callbacks.get());
301   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(1), uuid1, gid1));
302   DeviceGroups::AddFromStorage(GetTestAddress(1), dev1_storage);
303 
304   // Restore dev2 from the byte buffer
305   EXPECT_CALL(*callbacks, OnGroupAdded(GetTestAddress(2), uuid2, gid2));
306   EXPECT_CALL(*callbacks, OnGroupMemberAdded(GetTestAddress(2), gid1)).Times(1);
307   DeviceGroups::AddFromStorage(GetTestAddress(2), dev2_storage);
308 
309   DeviceGroups::CleanUp(callbacks.get());
310 }
311 
312 }  // namespace groups
313 }  // namespace bluetooth
314