1 //
2 //  Copyright (C) 2015 Google, Inc.
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 <base/macros.h>
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 #include "service/gatt_client.h"
22 #include "service/hal/fake_bluetooth_gatt_interface.h"
23 
24 using ::testing::_;
25 using ::testing::Return;
26 
27 namespace bluetooth {
28 namespace {
29 
30 class MockGattHandler
31     : public hal::FakeBluetoothGattInterface::TestClientHandler {
32  public:
33   MockGattHandler() = default;
34   ~MockGattHandler() override = default;
35 
36   MOCK_METHOD1(RegisterClient, bt_status_t(bt_uuid_t*));
37   MOCK_METHOD1(UnregisterClient, bt_status_t(int));
38   MOCK_METHOD1(Scan, bt_status_t(bool));
39   MOCK_METHOD4(Connect, bt_status_t(int , const bt_bdaddr_t *, bool, int));
40   MOCK_METHOD3(Disconnect, bt_status_t(int , const bt_bdaddr_t *, int));
41 
42   // Stub implementations for uninteresting TestClientHandler methods:
MultiAdvEnable(int,int,int,int,int,int,int)43   bt_status_t MultiAdvEnable(int, int, int, int, int, int, int) override {
44     return BT_STATUS_FAIL;
45   }
46 
MultiAdvSetInstData(int,bool,bool,bool,int,int,char *,int,char *,int,char *)47   bt_status_t MultiAdvSetInstData(int, bool, bool, bool, int,
48                                   int, char*, int, char*, int, char*) override {
49     return BT_STATUS_FAIL;
50   }
51 
MultiAdvDisable(int)52   bt_status_t MultiAdvDisable(int) override {
53     return BT_STATUS_FAIL;
54   }
55 
56  private:
57   DISALLOW_COPY_AND_ASSIGN(MockGattHandler);
58 };
59 
60 class GattClientTest : public ::testing::Test {
61  public:
62   GattClientTest() = default;
63   ~GattClientTest() override = default;
64 
SetUp()65   void SetUp() override {
66     // Only set |mock_handler_| if a previous test case hasn't set it.
67     if (!mock_handler_)
68       mock_handler_.reset(new MockGattHandler());
69 
70     fake_hal_gatt_iface_ = new hal::FakeBluetoothGattInterface(
71         std::static_pointer_cast<
72             hal::FakeBluetoothGattInterface::TestClientHandler>(mock_handler_),
73         nullptr);
74     hal::BluetoothGattInterface::InitializeForTesting(fake_hal_gatt_iface_);
75 
76     factory_.reset(new GattClientFactory());
77   }
78 
TearDown()79   void TearDown() override {
80     factory_.reset();
81     hal::BluetoothGattInterface::CleanUp();
82   }
83 
84  protected:
85   hal::FakeBluetoothGattInterface* fake_hal_gatt_iface_;
86   std::shared_ptr<MockGattHandler> mock_handler_;
87   std::unique_ptr<GattClientFactory> factory_;
88 
89  private:
90   DISALLOW_COPY_AND_ASSIGN(GattClientTest);
91 };
92 
TEST_F(GattClientTest,RegisterInstance)93 TEST_F(GattClientTest, RegisterInstance) {
94   EXPECT_CALL(*mock_handler_, RegisterClient(_))
95       .Times(2)
96       .WillOnce(Return(BT_STATUS_FAIL))
97       .WillOnce(Return(BT_STATUS_SUCCESS));
98 
99   // These will be asynchronously populated with a result when the callback
100   // executes.
101   BLEStatus status = BLE_STATUS_SUCCESS;
102   UUID cb_uuid;
103   std::unique_ptr<GattClient> client;
104   int callback_count = 0;
105 
106   auto callback = [&](BLEStatus in_status, const UUID& uuid,
107                       std::unique_ptr<BluetoothInstance> in_client) {
108         status = in_status;
109         cb_uuid = uuid;
110         client = std::unique_ptr<GattClient>(
111             static_cast<GattClient*>(in_client.release()));
112         callback_count++;
113       };
114 
115   UUID uuid0 = UUID::GetRandom();
116 
117   // HAL returns failure.
118   EXPECT_FALSE(factory_->RegisterInstance(uuid0, callback));
119   EXPECT_EQ(0, callback_count);
120 
121   // HAL returns success.
122   EXPECT_TRUE(factory_->RegisterInstance(uuid0, callback));
123   EXPECT_EQ(0, callback_count);
124 
125   // Calling twice with the same UUID should fail with no additional call into
126   // the stack.
127   EXPECT_FALSE(factory_->RegisterInstance(uuid0, callback));
128 
129   testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
130 
131   // Call with a different UUID while one is pending.
132   UUID uuid1 = UUID::GetRandom();
133   EXPECT_CALL(*mock_handler_, RegisterClient(_))
134       .Times(1)
135       .WillOnce(Return(BT_STATUS_SUCCESS));
136   EXPECT_TRUE(factory_->RegisterInstance(uuid1, callback));
137 
138   // Trigger callback with an unknown UUID. This should get ignored.
139   UUID uuid2 = UUID::GetRandom();
140   bt_uuid_t hal_uuid = uuid2.GetBlueDroid();
141   fake_hal_gatt_iface_->NotifyRegisterClientCallback(0, 0, hal_uuid);
142   EXPECT_EQ(0, callback_count);
143 
144   // |uuid0| succeeds.
145   int client_id0 = 2;  // Pick something that's not 0.
146   hal_uuid = uuid0.GetBlueDroid();
147   fake_hal_gatt_iface_->NotifyRegisterClientCallback(
148       BT_STATUS_SUCCESS, client_id0, hal_uuid);
149 
150   EXPECT_EQ(1, callback_count);
151   ASSERT_TRUE(client.get() != nullptr);  // Assert to terminate in case of error
152   EXPECT_EQ(BLE_STATUS_SUCCESS, status);
153   EXPECT_EQ(client_id0, client->GetInstanceId());
154   EXPECT_EQ(uuid0, client->GetAppIdentifier());
155   EXPECT_EQ(uuid0, cb_uuid);
156 
157   // The client should unregister itself when deleted.
158   EXPECT_CALL(*mock_handler_, UnregisterClient(client_id0))
159       .Times(1)
160       .WillOnce(Return(BT_STATUS_SUCCESS));
161   client.reset();
162   testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
163 
164   // |uuid1| fails.
165   int client_id1 = 3;
166   hal_uuid = uuid1.GetBlueDroid();
167   fake_hal_gatt_iface_->NotifyRegisterClientCallback(
168       BT_STATUS_FAIL, client_id1, hal_uuid);
169 
170   EXPECT_EQ(2, callback_count);
171   ASSERT_TRUE(client.get() == nullptr);  // Assert to terminate in case of error
172   EXPECT_EQ(BLE_STATUS_FAILURE, status);
173   EXPECT_EQ(uuid1, cb_uuid);
174 }
175 
TEST_F(GattClientTest,StartStopScan)176 TEST_F(GattClientTest, StartStopScan) {
177   EXPECT_CALL(*mock_handler_, Scan(true))
178       .Times(1)
179       .WillOnce(Return(BT_STATUS_SUCCESS));
180 
181   EXPECT_CALL(*mock_handler_, Scan(false))
182       .Times(1)
183       .WillOnce(Return(BT_STATUS_SUCCESS));
184 
185   for (int i = 0; i < 5; i++)
186     hal::BluetoothGattInterface::Get()->StartScan(i);
187 
188   for (int i = 0; i < 5; i++)
189     hal::BluetoothGattInterface::Get()->StopScan(i);
190 
191   testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
192 }
193 
194 }  // namespace
195 }  // namespace bluetooth
196