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