1 /******************************************************************************
2 *
3 * Copyright 2017 Google, Inc.
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 "btif/include/btif_profile_queue.h"
19
20 #include <base/functional/bind.h>
21 #include <base/functional/callback.h>
22 #include <base/location.h>
23 #include <gtest/gtest.h>
24
25 #include "btif/include/btif_common.h"
26 #include "btif/include/stack_manager_t.h"
27 #include "types/bluetooth/uuid.h"
28 #include "types/raw_address.h"
29
30 typedef void(tBTIF_CBACK)(uint16_t event, char* p_param);
31 typedef void(tBTIF_COPY_CBACK)(uint16_t event, char* p_dest, const char* p_src);
32
33 // NOTE: Local re-implementation of functions to avoid thread context switching
34 static bool sStackRunning;
get_stack_is_running(void)35 static bool get_stack_is_running(void) { return sStackRunning; }
36 static stack_manager_t sStackManager = {
37 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, get_stack_is_running};
stack_manager_get_interface()38 const stack_manager_t* stack_manager_get_interface() { return &sStackManager; }
do_in_jni_thread(base::OnceClosure task)39 bt_status_t do_in_jni_thread(base::OnceClosure task) {
40 std::move(task).Run();
41 return BT_STATUS_SUCCESS;
42 }
is_on_jni_thread()43 bool is_on_jni_thread() { return true; }
44
45 enum ResultType { NOT_SET = 0, UNKNOWN, UUID1_ADDR1, UUID1_ADDR2, UUID2_ADDR1, UUID2_ADDR2 };
46
47 static ResultType sResult;
48
49 class BtifProfileQueueTest : public ::testing::Test {
50 public:
51 static const uint16_t kTestUuid1 = 0x9527;
52 static const uint16_t kTestUuid2 = 0x819F;
53 static const RawAddress kTestAddr1;
54 static const RawAddress kTestAddr2;
55
56 protected:
SetUp()57 void SetUp() override {
58 sStackRunning = true;
59 sResult = NOT_SET;
60 }
TearDown()61 void TearDown() override { btif_queue_release(); }
62 };
63
64 const RawAddress BtifProfileQueueTest::kTestAddr1{{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}};
65 const RawAddress BtifProfileQueueTest::kTestAddr2{{0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56}};
66
test_connect_cb(RawAddress * bda,uint16_t uuid)67 static bt_status_t test_connect_cb(RawAddress* bda, uint16_t uuid) {
68 sResult = UNKNOWN;
69 if (*bda == BtifProfileQueueTest::kTestAddr1) {
70 if (uuid == BtifProfileQueueTest::kTestUuid1) {
71 sResult = UUID1_ADDR1;
72 } else if (uuid == BtifProfileQueueTest::kTestUuid2) {
73 sResult = UUID2_ADDR1;
74 }
75 } else if (*bda == BtifProfileQueueTest::kTestAddr2) {
76 if (uuid == BtifProfileQueueTest::kTestUuid1) {
77 sResult = UUID1_ADDR2;
78 } else if (uuid == BtifProfileQueueTest::kTestUuid2) {
79 sResult = UUID2_ADDR2;
80 }
81 }
82 return BT_STATUS_SUCCESS;
83 }
84
TEST_F(BtifProfileQueueTest,test_connect)85 TEST_F(BtifProfileQueueTest, test_connect) {
86 sResult = NOT_SET;
87 btif_queue_connect(kTestUuid1, &kTestAddr1, test_connect_cb);
88 EXPECT_EQ(sResult, UUID1_ADDR1);
89 }
90
test_connect_cb_fail(RawAddress * bda,uint16_t uuid)91 static bt_status_t test_connect_cb_fail(RawAddress* bda, uint16_t uuid) {
92 sResult = UNKNOWN;
93 if (*bda == BtifProfileQueueTest::kTestAddr1) {
94 if (uuid == BtifProfileQueueTest::kTestUuid1) {
95 sResult = UUID1_ADDR1;
96 } else if (uuid == BtifProfileQueueTest::kTestUuid2) {
97 sResult = UUID2_ADDR1;
98 }
99 } else if (*bda == BtifProfileQueueTest::kTestAddr2) {
100 if (uuid == BtifProfileQueueTest::kTestUuid1) {
101 sResult = UUID1_ADDR2;
102 } else if (uuid == BtifProfileQueueTest::kTestUuid2) {
103 sResult = UUID2_ADDR2;
104 }
105 }
106 return BT_STATUS_BUSY;
107 }
108
TEST_F(BtifProfileQueueTest,test_connect_fail_still_can_advance_the_queue)109 TEST_F(BtifProfileQueueTest, test_connect_fail_still_can_advance_the_queue) {
110 sResult = NOT_SET;
111 // First connect-message for UUID1-ADDR1 is executed, but does not be removed
112 // from connect-queue yet.
113 btif_queue_connect(kTestUuid1, &kTestAddr1, test_connect_cb);
114 EXPECT_EQ(sResult, UUID1_ADDR1);
115 sResult = NOT_SET;
116 // Second connect-message for UUID2-ADDR1 be pushed into connect-queue, but is
117 // not executed
118 btif_queue_connect(kTestUuid2, &kTestAddr1, test_connect_cb_fail);
119 EXPECT_EQ(sResult, NOT_SET);
120 // Third connect-message for UUID1-ADDR2 be pushed into connect-queue, but is
121 // not executed
122 btif_queue_connect(kTestUuid1, &kTestAddr2, test_connect_cb_fail);
123 EXPECT_EQ(sResult, NOT_SET);
124 // Fourth connect-message for UUID2-ADDR2 be pushed into connect-queue, but is
125 // not executed
126 btif_queue_connect(kTestUuid2, &kTestAddr2, test_connect_cb_fail);
127 EXPECT_EQ(sResult, NOT_SET);
128 // removed First connect-message from connect-queue, check it can advance to
129 // subsequent connect-message.
130 btif_queue_advance();
131 EXPECT_EQ(sResult, UUID2_ADDR2);
132 }
133
TEST_F(BtifProfileQueueTest,test_connect_same_uuid_do_not_repeat)134 TEST_F(BtifProfileQueueTest, test_connect_same_uuid_do_not_repeat) {
135 sResult = NOT_SET;
136 btif_queue_connect(kTestUuid1, &kTestAddr1, test_connect_cb);
137 EXPECT_EQ(sResult, UUID1_ADDR1);
138 // Second connection request on the same UUID do not repeat
139 sResult = NOT_SET;
140 btif_queue_connect(kTestUuid1, &kTestAddr1, test_connect_cb);
141 EXPECT_EQ(sResult, NOT_SET);
142 // Not even after we advance the queue
143 sResult = NOT_SET;
144 btif_queue_advance();
145 btif_queue_connect_next();
146 EXPECT_EQ(sResult, NOT_SET);
147 }
148
TEST_F(BtifProfileQueueTest,test_multiple_connects)149 TEST_F(BtifProfileQueueTest, test_multiple_connects) {
150 // First item is executed
151 sResult = NOT_SET;
152 btif_queue_connect(kTestUuid1, &kTestAddr1, test_connect_cb);
153 EXPECT_EQ(sResult, UUID1_ADDR1);
154 // Second item with advance is executed
155 sResult = NOT_SET;
156 btif_queue_advance();
157 btif_queue_connect(kTestUuid2, &kTestAddr1, test_connect_cb);
158 EXPECT_EQ(sResult, UUID2_ADDR1);
159 }
160
TEST_F(BtifProfileQueueTest,test_multiple_connects_without_advance)161 TEST_F(BtifProfileQueueTest, test_multiple_connects_without_advance) {
162 // First item is executed
163 sResult = NOT_SET;
164 btif_queue_connect(kTestUuid1, &kTestAddr1, test_connect_cb);
165 EXPECT_EQ(sResult, UUID1_ADDR1);
166 // Second item without advance is not executed
167 sResult = NOT_SET;
168 btif_queue_connect(kTestUuid2, &kTestAddr1, test_connect_cb);
169 EXPECT_EQ(sResult, NOT_SET);
170 // Third item for same UUID1, but different address ADDR2
171 sResult = NOT_SET;
172 btif_queue_connect(kTestUuid1, &kTestAddr2, test_connect_cb);
173 EXPECT_EQ(sResult, NOT_SET);
174 // Fourth item for same UUID2, but different address ADDR2
175 sResult = NOT_SET;
176 btif_queue_connect(kTestUuid2, &kTestAddr2, test_connect_cb);
177 EXPECT_EQ(sResult, NOT_SET);
178 // Connect next doesn't work
179 sResult = NOT_SET;
180 btif_queue_connect_next();
181 EXPECT_EQ(sResult, NOT_SET);
182 // Advance moves queue to execute second item
183 sResult = NOT_SET;
184 btif_queue_advance();
185 EXPECT_EQ(sResult, UUID2_ADDR1);
186 // Advance moves queue to execute third item
187 sResult = NOT_SET;
188 btif_queue_advance();
189 EXPECT_EQ(sResult, UUID1_ADDR2);
190 // Advance moves queue to execute fourth item
191 sResult = NOT_SET;
192 btif_queue_advance();
193 EXPECT_EQ(sResult, UUID2_ADDR2);
194 }
195
TEST_F(BtifProfileQueueTest,test_cleanup_first_allow_second)196 TEST_F(BtifProfileQueueTest, test_cleanup_first_allow_second) {
197 // First item is executed
198 sResult = NOT_SET;
199 btif_queue_connect(kTestUuid1, &kTestAddr1, test_connect_cb);
200 EXPECT_EQ(sResult, UUID1_ADDR1);
201 // Second item without advance is not executed
202 sResult = NOT_SET;
203 btif_queue_connect(kTestUuid2, &kTestAddr1, test_connect_cb);
204 EXPECT_EQ(sResult, NOT_SET);
205 // Connect next doesn't work
206 sResult = NOT_SET;
207 btif_queue_connect_next();
208 EXPECT_EQ(sResult, NOT_SET);
209 // Cleanup UUID1 allows the next profile connection to be executed
210 sResult = NOT_SET;
211 btif_queue_cleanup(kTestUuid1);
212 btif_queue_connect_next();
213 EXPECT_EQ(sResult, UUID2_ADDR1);
214 }
215
TEST_F(BtifProfileQueueTest,test_cleanup_both)216 TEST_F(BtifProfileQueueTest, test_cleanup_both) {
217 // First item is executed
218 sResult = NOT_SET;
219 btif_queue_connect(kTestUuid1, &kTestAddr1, test_connect_cb);
220 EXPECT_EQ(sResult, UUID1_ADDR1);
221 // Second item without advance is not executed
222 sResult = NOT_SET;
223 btif_queue_connect(kTestUuid2, &kTestAddr1, test_connect_cb);
224 EXPECT_EQ(sResult, NOT_SET);
225 // Connect next doesn't work
226 sResult = NOT_SET;
227 btif_queue_connect_next();
228 EXPECT_EQ(sResult, NOT_SET);
229 // Cleanup both leaves nothing to execute
230 sResult = NOT_SET;
231 btif_queue_cleanup(kTestUuid1);
232 btif_queue_cleanup(kTestUuid2);
233 btif_queue_connect_next();
234 EXPECT_EQ(sResult, NOT_SET);
235 }
236
TEST_F(BtifProfileQueueTest,test_cleanup_both_reverse_order)237 TEST_F(BtifProfileQueueTest, test_cleanup_both_reverse_order) {
238 // First item is executed
239 sResult = NOT_SET;
240 btif_queue_connect(kTestUuid1, &kTestAddr1, test_connect_cb);
241 EXPECT_EQ(sResult, UUID1_ADDR1);
242 // Second item without advance is not executed
243 sResult = NOT_SET;
244 btif_queue_connect(kTestUuid2, &kTestAddr1, test_connect_cb);
245 EXPECT_EQ(sResult, NOT_SET);
246 // Connect next doesn't work
247 sResult = NOT_SET;
248 btif_queue_connect_next();
249 EXPECT_EQ(sResult, NOT_SET);
250 // Cleanup both in reverse order leaves nothing to execute
251 sResult = NOT_SET;
252 btif_queue_cleanup(kTestUuid2);
253 btif_queue_cleanup(kTestUuid1);
254 btif_queue_connect_next();
255 EXPECT_EQ(sResult, NOT_SET);
256 }
257