• 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 <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