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