1 /*
2 * Copyright 2020 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/classic/internal/link.h"
18
19 #include "hci/acl_manager_mock.h"
20 #include "hci/address.h"
21 #include "l2cap/classic/internal/dynamic_channel_service_impl_mock.h"
22 #include "l2cap/classic/internal/dynamic_channel_service_manager_impl_mock.h"
23 #include "l2cap/classic/internal/fixed_channel_service_manager_impl_mock.h"
24 #include "l2cap/internal/parameter_provider_mock.h"
25
26 #include <gmock/gmock-nice-strict.h>
27 #include <gmock/gmock.h>
28 #include <gtest/gtest.h>
29
30 using ::testing::NiceMock;
31
32 namespace bluetooth {
33 namespace l2cap {
34 namespace classic {
35 namespace internal {
36 namespace {
37
38 constexpr Psm kPsm = 123;
39 constexpr Cid kCid = 456;
40
41 using classic::internal::testing::MockDynamicChannelServiceImpl;
42 using classic::internal::testing::MockDynamicChannelServiceManagerImpl;
43 using hci::testing::MockClassicAclConnection;
44 using l2cap::internal::testing::MockParameterProvider;
45 using testing::MockFixedChannelServiceManagerImpl;
46
47 class L2capClassicLinkTest : public ::testing::Test {
48 public:
OnOpen(std::unique_ptr<DynamicChannel> channel)49 void OnOpen(std::unique_ptr<DynamicChannel> channel) {
50 on_open_promise_.set_value();
51 }
52
OnFail(DynamicChannelManager::ConnectionResult result)53 void OnFail(DynamicChannelManager::ConnectionResult result) {
54 on_fail_promise_.set_value();
55 }
56
OnDequeueCallbackForTest()57 void OnDequeueCallbackForTest() {
58 std::unique_ptr<BasePacketBuilder> data = raw_acl_connection_->acl_queue_.GetDownEnd()->TryDequeue();
59 if (data != nullptr) {
60 dequeue_promise_.set_value();
61 }
62 }
63
EnqueueCallbackForTest()64 void EnqueueCallbackForTest() {
65 raw_acl_connection_->acl_queue_.GetDownEnd()->RegisterDequeue(
66 handler_, common::Bind(&L2capClassicLinkTest::OnDequeueCallbackForTest, common::Unretained(this)));
67 }
68
DequeueCallback()69 void DequeueCallback() {
70 raw_acl_connection_->acl_queue_.GetDownEnd()->UnregisterDequeue();
71 }
72
73 protected:
SetUp()74 void SetUp() override {
75 thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL);
76 handler_ = new os::Handler(thread_);
77 signalling_handler_ = new os::Handler(thread_);
78
79 raw_acl_connection_ = new NiceMock<MockClassicAclConnection>();
80 link_ = new Link(signalling_handler_, std::unique_ptr<MockClassicAclConnection>(raw_acl_connection_),
81 &mock_parameter_provider_, &mock_classic_dynamic_channel_service_manager_,
82 &mock_classic_fixed_channel_service_manager_, nullptr);
83 }
84
TearDown()85 void TearDown() override {
86 delete link_;
87
88 signalling_handler_->Clear();
89 delete signalling_handler_;
90
91 handler_->Clear();
92 delete handler_;
93
94 delete thread_;
95 }
96
97 os::Thread* thread_ = nullptr;
98 os::Handler* handler_ = nullptr;
99 os::Handler* signalling_handler_ = nullptr;
100
101 MockClassicAclConnection* raw_acl_connection_ = nullptr;
102 std::unique_ptr<MockClassicAclConnection> acl_connection_;
103
104 NiceMock<MockParameterProvider> mock_parameter_provider_;
105 MockFixedChannelServiceManagerImpl mock_classic_fixed_channel_service_manager_;
106 MockDynamicChannelServiceManagerImpl mock_classic_dynamic_channel_service_manager_;
107 SecurityEnforcementRejectAllImpl security_module_impl_;
108
109 std::promise<void> on_open_promise_;
110 std::promise<void> on_fail_promise_;
111 std::promise<void> dequeue_promise_;
112
113 Link* link_;
114 };
115
TEST_F(L2capClassicLinkTest,pending_channels_get_notified_on_acl_disconnect)116 TEST_F(L2capClassicLinkTest, pending_channels_get_notified_on_acl_disconnect) {
117 EnqueueCallbackForTest();
118
119 Link::PendingDynamicChannelConnection pending_dynamic_channel_connection{
120 .on_open_callback_ = handler_->BindOn(this, &L2capClassicLinkTest::OnOpen),
121 .on_fail_callback_ = handler_->BindOnceOn(this, &L2capClassicLinkTest::OnFail),
122 .configuration_ = DynamicChannelConfigurationOption(),
123 };
124 auto future = on_fail_promise_.get_future();
125
126 MockDynamicChannelServiceImpl service;
127 ON_CALL(service, GetSecurityPolicy())
128 .WillByDefault(::testing::Return(SecurityPolicy::_SDP_ONLY_NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK));
129
130 EXPECT_CALL(mock_classic_dynamic_channel_service_manager_, GetSecurityEnforcementInterface())
131 .WillOnce(::testing::Return(&security_module_impl_));
132 EXPECT_CALL(mock_classic_dynamic_channel_service_manager_, GetService(::testing::_))
133 .WillRepeatedly(::testing::Return(&service));
134
135 link_->SendConnectionRequest(kPsm, kCid, std::move(pending_dynamic_channel_connection));
136 link_->OnAclDisconnected(hci::ErrorCode::UNKNOWN_HCI_COMMAND);
137 future.wait();
138
139 auto dequeue_future = dequeue_promise_.get_future();
140 dequeue_future.wait();
141 DequeueCallback();
142 }
143
144 } // namespace
145 } // namespace internal
146 } // namespace classic
147 } // namespace l2cap
148 } // namespace bluetooth
149