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