1 /*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "l2cap/internal/dynamic_channel_impl.h"
18
19 #include "common/testing/bind_test_util.h"
20 #include "l2cap/cid.h"
21 #include "l2cap/classic/internal/link_mock.h"
22 #include "l2cap/internal/parameter_provider_mock.h"
23 #include "os/handler.h"
24
25 #include <gmock/gmock.h>
26 #include <gtest/gtest.h>
27
28 namespace bluetooth {
29 namespace l2cap {
30 namespace internal {
31
32 using classic::internal::testing::MockLink;
33 using l2cap::internal::testing::MockParameterProvider;
34 using ::testing::Return;
35
36 class L2capClassicDynamicChannelImplTest : public ::testing::Test {
37 public:
SyncHandler(os::Handler * handler)38 static void SyncHandler(os::Handler* handler) {
39 std::promise<void> promise;
40 auto future = promise.get_future();
41 handler->Post(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise)));
42 future.wait_for(std::chrono::milliseconds(3));
43 }
44
45 protected:
SetUp()46 void SetUp() override {
47 thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL);
48 l2cap_handler_ = new os::Handler(thread_);
49 }
50
TearDown()51 void TearDown() override {
52 l2cap_handler_->Clear();
53 delete l2cap_handler_;
54 delete thread_;
55 }
56
57 os::Thread* thread_ = nullptr;
58 os::Handler* l2cap_handler_ = nullptr;
59 };
60
61 class StatusCapture {
62 public:
63 hci::ErrorCode value = hci::ErrorCode::SUCCESS;
capture(hci::ErrorCode status)64 void capture(hci::ErrorCode status) {
65 value = status;
66 }
67 };
68
TEST_F(L2capClassicDynamicChannelImplTest,get_device)69 TEST_F(L2capClassicDynamicChannelImplTest, get_device) {
70 MockParameterProvider mock_parameter_provider;
71 MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
72 const hci::AddressWithType device{{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
73 EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
74 DynamicChannelImpl dynamic_channel_impl(0x01, kFirstDynamicChannel, kFirstDynamicChannel, &mock_classic_link,
75 l2cap_handler_);
76 EXPECT_EQ(device, dynamic_channel_impl.GetDevice());
77 }
78
TEST_F(L2capClassicDynamicChannelImplTest,close_triggers_callback)79 TEST_F(L2capClassicDynamicChannelImplTest, close_triggers_callback) {
80 MockParameterProvider mock_parameter_provider;
81 MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
82 const hci::AddressWithType device{{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
83 EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
84 DynamicChannelImpl dynamic_channel_impl(0x01, kFirstDynamicChannel, kFirstDynamicChannel, &mock_classic_link,
85 l2cap_handler_);
86
87 // Register on close callback
88 auto user_handler = std::make_unique<os::Handler>(thread_);
89 StatusCapture* my_status = new StatusCapture();
90 dynamic_channel_impl.RegisterOnCloseCallback(user_handler->BindOnceOn(my_status, &StatusCapture::capture));
91
92 // Channel closure should trigger such callback
93 dynamic_channel_impl.OnClosed(hci::ErrorCode::REMOTE_USER_TERMINATED_CONNECTION);
94 SyncHandler(user_handler.get());
95 EXPECT_EQ(hci::ErrorCode::REMOTE_USER_TERMINATED_CONNECTION, my_status->value);
96
97 user_handler->Clear();
98 delete my_status;
99 }
100
TEST_F(L2capClassicDynamicChannelImplTest,register_callback_after_close_should_call_immediately)101 TEST_F(L2capClassicDynamicChannelImplTest, register_callback_after_close_should_call_immediately) {
102 MockParameterProvider mock_parameter_provider;
103 MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
104 const hci::AddressWithType device{{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
105 EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
106 DynamicChannelImpl dynamic_channel_impl(0x01, kFirstDynamicChannel, kFirstDynamicChannel, &mock_classic_link,
107 l2cap_handler_);
108
109 // Channel closure should do nothing
110 dynamic_channel_impl.OnClosed(hci::ErrorCode::REMOTE_USER_TERMINATED_CONNECTION);
111
112 // Register on close callback should trigger callback immediately
113 auto user_handler = std::make_unique<os::Handler>(thread_);
114 StatusCapture* my_status = new StatusCapture();
115 dynamic_channel_impl.RegisterOnCloseCallback(user_handler->BindOnceOn(my_status, &StatusCapture::capture));
116
117 SyncHandler(user_handler.get());
118 EXPECT_EQ(hci::ErrorCode::REMOTE_USER_TERMINATED_CONNECTION, my_status->value);
119
120 user_handler->Clear();
121 delete my_status;
122 }
123
TEST_F(L2capClassicDynamicChannelImplTest,close_twice_should_fail)124 TEST_F(L2capClassicDynamicChannelImplTest, close_twice_should_fail) {
125 MockParameterProvider mock_parameter_provider;
126 MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
127 const hci::AddressWithType device{{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
128 EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
129 DynamicChannelImpl dynamic_channel_impl(0x01, kFirstDynamicChannel, kFirstDynamicChannel, &mock_classic_link,
130 l2cap_handler_);
131
132 // Register on close callback
133 auto user_handler = std::make_unique<os::Handler>(thread_);
134 StatusCapture* my_status = new StatusCapture();
135 dynamic_channel_impl.RegisterOnCloseCallback(user_handler->BindOnceOn(my_status, &StatusCapture::capture));
136
137 // Channel closure should trigger such callback
138 dynamic_channel_impl.OnClosed(hci::ErrorCode::REMOTE_USER_TERMINATED_CONNECTION);
139 SyncHandler(user_handler.get());
140 EXPECT_EQ(hci::ErrorCode::REMOTE_USER_TERMINATED_CONNECTION, my_status->value);
141
142 // 2nd OnClose() callback should fail
143 EXPECT_DEATH(dynamic_channel_impl.OnClosed(hci::ErrorCode::PAGE_TIMEOUT), ".*OnClosed.*");
144
145 user_handler->Clear();
146 delete my_status;
147 }
148
TEST_F(L2capClassicDynamicChannelImplTest,multiple_registeration_should_fail)149 TEST_F(L2capClassicDynamicChannelImplTest, multiple_registeration_should_fail) {
150 MockParameterProvider mock_parameter_provider;
151 MockLink mock_classic_link(l2cap_handler_, &mock_parameter_provider);
152 const hci::AddressWithType device{{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}}, hci::AddressType::PUBLIC_IDENTITY_ADDRESS};
153 EXPECT_CALL(mock_classic_link, GetDevice()).WillRepeatedly(Return(device));
154 DynamicChannelImpl dynamic_channel_impl(0x01, kFirstDynamicChannel, kFirstDynamicChannel, &mock_classic_link,
155 l2cap_handler_);
156
157 // Register on close callback
158 auto user_handler = std::make_unique<os::Handler>(thread_);
159 StatusCapture* my_status = new StatusCapture();
160 dynamic_channel_impl.RegisterOnCloseCallback(user_handler->BindOnceOn(my_status, &StatusCapture::capture));
161
162 EXPECT_DEATH(
163 dynamic_channel_impl.RegisterOnCloseCallback(user_handler->BindOnce([](hci::ErrorCode status) { FAIL(); })),
164 ".*RegisterOnCloseCallback.*");
165
166 user_handler->Clear();
167 delete my_status;
168 }
169
170 } // namespace internal
171 } // namespace l2cap
172 } // namespace bluetooth
173