• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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