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 24using ::testing::_; 25using ::testing::Return; 26 27namespace bluetooth { 28namespace { 29 30class 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: 43 bt_status_t MultiAdvEnable(int, int, int, int, int, int, int) override { 44 return BT_STATUS_FAIL; 45 } 46 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 52 bt_status_t MultiAdvDisable(int) override { 53 return BT_STATUS_FAIL; 54 } 55 56 private: 57 DISALLOW_COPY_AND_ASSIGN(MockGattHandler); 58}; 59 60class GattClientTest : public ::testing::Test { 61 public: 62 GattClientTest() = default; 63 ~GattClientTest() override = default; 64 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 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 93TEST_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 176TEST_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