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