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