1c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// 2c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// Copyright (C) 2015 Google, Inc. 3c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// 4c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// Licensed under the Apache License, Version 2.0 (the "License"); 5c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// you may not use this file except in compliance with the License. 6c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// You may obtain a copy of the License at: 7c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// 8c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// http://www.apache.org/licenses/LICENSE-2.0 9c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// 10c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// Unless required by applicable law or agreed to in writing, software 11c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// distributed under the License is distributed on an "AS IS" BASIS, 12c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// See the License for the specific language governing permissions and 14c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// limitations under the License. 15c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray// 16c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 17c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray#include <base/macros.h> 18c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray#include <gmock/gmock.h> 19c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray#include <gtest/gtest.h> 20c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 2160b0e8f7ef14b1c0bd0e6d86656cd912dd4c4221Jakub Pawlowski#include "service/adapter.h" 22c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray#include "service/hal/fake_bluetooth_gatt_interface.h" 23c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray#include "service/low_energy_client.h" 2412338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray#include "stack/include/bt_types.h" 2512338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray#include "stack/include/hcidefs.h" 2660b0e8f7ef14b1c0bd0e6d86656cd912dd4c4221Jakub Pawlowski#include "test/mock_adapter.h" 27c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 28c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Ugurayusing ::testing::_; 29c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Ugurayusing ::testing::Return; 30a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowskiusing ::testing::Pointee; 31a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowskiusing ::testing::DoAll; 32a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowskiusing ::testing::Invoke; 33c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 34c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguraynamespace bluetooth { 35c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguraynamespace { 36c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 379e5205368d61adf11e75c9e2bd9f6ff26b375bacArman Ugurayclass MockGattHandler 389e5205368d61adf11e75c9e2bd9f6ff26b375bacArman Uguray : public hal::FakeBluetoothGattInterface::TestClientHandler { 39c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray public: 40911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson MockGattHandler(){}; 41c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray ~MockGattHandler() override = default; 42c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 4396ac0a3c16a4a9f98169baf158bae16528cde79bJakub Pawlowski MOCK_METHOD1(RegisterClient, bt_status_t(const bt_uuid_t&)); 44c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray MOCK_METHOD1(UnregisterClient, bt_status_t(int)); 459e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski MOCK_METHOD4(Connect, bt_status_t(int, const RawAddress&, bool, int)); 469e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski MOCK_METHOD3(Disconnect, bt_status_t(int, const RawAddress&, int)); 47c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 48c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray private: 49c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray DISALLOW_COPY_AND_ASSIGN(MockGattHandler); 50c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray}; 51c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 5282ea72f905565f83116f74d5ccbacea5d710a853Arman Ugurayclass TestDelegate : public LowEnergyClient::Delegate { 5382ea72f905565f83116f74d5ccbacea5d710a853Arman Uguray public: 54911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson TestDelegate() : connection_state_count_(0), last_mtu_(0) {} 5582ea72f905565f83116f74d5ccbacea5d710a853Arman Uguray 5682ea72f905565f83116f74d5ccbacea5d710a853Arman Uguray ~TestDelegate() override = default; 5782ea72f905565f83116f74d5ccbacea5d710a853Arman Uguray 58a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski int connection_state_count() const { return connection_state_count_; } 59a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski 60a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski void OnConnectionState(LowEnergyClient* client, int status, 61911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson const char* address, bool connected) { 62a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski ASSERT_TRUE(client); 63a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski connection_state_count_++; 64a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski } 65a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski 66a6551079fe71b1c76505ada0e4f758f6faf651e0Jakub Pawlowski void OnMtuChanged(LowEnergyClient* client, int status, const char* address, 67a6551079fe71b1c76505ada0e4f758f6faf651e0Jakub Pawlowski int mtu) { 68a6551079fe71b1c76505ada0e4f758f6faf651e0Jakub Pawlowski ASSERT_TRUE(client); 69a6551079fe71b1c76505ada0e4f758f6faf651e0Jakub Pawlowski last_mtu_ = mtu; 70a6551079fe71b1c76505ada0e4f758f6faf651e0Jakub Pawlowski } 71a6551079fe71b1c76505ada0e4f758f6faf651e0Jakub Pawlowski 7282ea72f905565f83116f74d5ccbacea5d710a853Arman Uguray private: 73a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski int connection_state_count_; 74a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski 75a6551079fe71b1c76505ada0e4f758f6faf651e0Jakub Pawlowski int last_mtu_; 76a6551079fe71b1c76505ada0e4f758f6faf651e0Jakub Pawlowski 7782ea72f905565f83116f74d5ccbacea5d710a853Arman Uguray DISALLOW_COPY_AND_ASSIGN(TestDelegate); 7882ea72f905565f83116f74d5ccbacea5d710a853Arman Uguray}; 7982ea72f905565f83116f74d5ccbacea5d710a853Arman Uguray 80c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Ugurayclass LowEnergyClientTest : public ::testing::Test { 81c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray public: 82c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray LowEnergyClientTest() = default; 83c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray ~LowEnergyClientTest() override = default; 84c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 85c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray void SetUp() override { 86ff651b7fd11daaa29732cb8735d248910d9248f9Ajay Panicker // Only set |mock_handler_| if a test hasn't set it. 87911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (!mock_handler_) mock_handler_.reset(new MockGattHandler()); 88c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray fake_hal_gatt_iface_ = new hal::FakeBluetoothGattInterface( 89911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson nullptr, nullptr, 909e5205368d61adf11e75c9e2bd9f6ff26b375bacArman Uguray std::static_pointer_cast< 919e5205368d61adf11e75c9e2bd9f6ff26b375bacArman Uguray hal::FakeBluetoothGattInterface::TestClientHandler>(mock_handler_), 929e5205368d61adf11e75c9e2bd9f6ff26b375bacArman Uguray nullptr); 93c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray hal::BluetoothGattInterface::InitializeForTesting(fake_hal_gatt_iface_); 9460b0e8f7ef14b1c0bd0e6d86656cd912dd4c4221Jakub Pawlowski ble_factory_.reset(new LowEnergyClientFactory(mock_adapter_)); 95c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray } 96c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 97c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray void TearDown() override { 98c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray ble_factory_.reset(); 99c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray hal::BluetoothGattInterface::CleanUp(); 100c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray } 101c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 102c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray protected: 103c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray hal::FakeBluetoothGattInterface* fake_hal_gatt_iface_; 10460b0e8f7ef14b1c0bd0e6d86656cd912dd4c4221Jakub Pawlowski testing::MockAdapter mock_adapter_; 105c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray std::shared_ptr<MockGattHandler> mock_handler_; 106c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray std::unique_ptr<LowEnergyClientFactory> ble_factory_; 107c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 108c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray private: 109c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray DISALLOW_COPY_AND_ASSIGN(LowEnergyClientTest); 110c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray}; 111c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 11212338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray// Used for tests that operate on a pre-registered client. 11312338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Ugurayclass LowEnergyClientPostRegisterTest : public LowEnergyClientTest { 11412338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray public: 115911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson LowEnergyClientPostRegisterTest() : next_client_id_(0) {} 11612338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray ~LowEnergyClientPostRegisterTest() override = default; 11712338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray 11812338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray void SetUp() override { 11912338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray LowEnergyClientTest::SetUp(); 12053cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski auto callback = [&](std::unique_ptr<LowEnergyClient> client) { 12153cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski le_client_ = std::move(client); 12253cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski }; 12353cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski RegisterTestClient(callback); 12453cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski } 12553cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski 12653cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski void TearDown() override { 12753cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski EXPECT_CALL(*mock_handler_, UnregisterClient(_)) 12853cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski .Times(1) 12953cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski .WillOnce(Return(BT_STATUS_SUCCESS)); 13053cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski le_client_.reset(); 13153cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski LowEnergyClientTest::TearDown(); 13253cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski } 13353cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski 13453cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski void RegisterTestClient( 13567d5a2523314d9757b2472c3e828dbc1015df4feJakub Pawlowski const std::function<void(std::unique_ptr<LowEnergyClient> client)> 13653cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski callback) { 13712338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray UUID uuid = UUID::GetRandom(); 13853cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski auto api_callback = [&](BLEStatus status, const UUID& in_uuid, 139911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson std::unique_ptr<BluetoothInstance> in_client) { 14012338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray CHECK(in_uuid == uuid); 14112338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray CHECK(in_client.get()); 14212338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray CHECK(status == BLE_STATUS_SUCCESS); 14312338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray 14453cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski callback(std::unique_ptr<LowEnergyClient>( 14553cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski static_cast<LowEnergyClient*>(in_client.release()))); 14612338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray }; 14712338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray 14812338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray EXPECT_CALL(*mock_handler_, RegisterClient(_)) 14912338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray .Times(1) 15012338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 15112338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray 15253cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski ble_factory_->RegisterInstance(uuid, api_callback); 15312338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray 15412338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray bt_uuid_t hal_uuid = uuid.GetBlueDroid(); 155911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson fake_hal_gatt_iface_->NotifyRegisterClientCallback(0, next_client_id_++, 156911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson hal_uuid); 15760b0e8f7ef14b1c0bd0e6d86656cd912dd4c4221Jakub Pawlowski ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get()); 15812338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray } 15912338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray 16012338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray protected: 16112338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray std::unique_ptr<LowEnergyClient> le_client_; 16212338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray 16312338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray private: 16453cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski int next_client_id_; 16553cfa7c612cda14aed96be45dced88b710b91df9Jakub Pawlowski 16612338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray DISALLOW_COPY_AND_ASSIGN(LowEnergyClientPostRegisterTest); 16712338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray}; 16812338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray 169bb18c41ffa0370d4eb0c4a15904b114355606466Arman UgurayTEST_F(LowEnergyClientTest, RegisterInstance) { 170c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray EXPECT_CALL(*mock_handler_, RegisterClient(_)) 171c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray .Times(2) 172c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray .WillOnce(Return(BT_STATUS_FAIL)) 173c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 174c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 175c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray // These will be asynchronously populated with a result when the callback 176c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray // executes. 177c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray BLEStatus status = BLE_STATUS_SUCCESS; 178c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray UUID cb_uuid; 179c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray std::unique_ptr<LowEnergyClient> client; 180c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray int callback_count = 0; 181c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 18208f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray auto callback = [&](BLEStatus in_status, const UUID& uuid, 183bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray std::unique_ptr<BluetoothInstance> in_client) { 184911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson status = in_status; 185911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson cb_uuid = uuid; 186911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson client = std::unique_ptr<LowEnergyClient>( 187911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson static_cast<LowEnergyClient*>(in_client.release())); 188911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson callback_count++; 189911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson }; 190c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 191c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray UUID uuid0 = UUID::GetRandom(); 192c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 193c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray // HAL returns failure. 194bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_FALSE(ble_factory_->RegisterInstance(uuid0, callback)); 195c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray EXPECT_EQ(0, callback_count); 196c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 197c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray // HAL returns success. 198bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_TRUE(ble_factory_->RegisterInstance(uuid0, callback)); 199c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray EXPECT_EQ(0, callback_count); 200c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 201c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray // Calling twice with the same UUID should fail with no additional call into 202c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray // the stack. 203bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_FALSE(ble_factory_->RegisterInstance(uuid0, callback)); 204c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 20560b0e8f7ef14b1c0bd0e6d86656cd912dd4c4221Jakub Pawlowski ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get()); 206c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 207c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray // Call with a different UUID while one is pending. 208c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray UUID uuid1 = UUID::GetRandom(); 209c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray EXPECT_CALL(*mock_handler_, RegisterClient(_)) 210c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray .Times(1) 211c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 212bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_TRUE(ble_factory_->RegisterInstance(uuid1, callback)); 213c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 214c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray // Trigger callback with an unknown UUID. This should get ignored. 215c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray UUID uuid2 = UUID::GetRandom(); 216c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray bt_uuid_t hal_uuid = uuid2.GetBlueDroid(); 217c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray fake_hal_gatt_iface_->NotifyRegisterClientCallback(0, 0, hal_uuid); 218c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray EXPECT_EQ(0, callback_count); 219c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 220c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray // |uuid0| succeeds. 221c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray int client_if0 = 2; // Pick something that's not 0. 222c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray hal_uuid = uuid0.GetBlueDroid(); 223911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson fake_hal_gatt_iface_->NotifyRegisterClientCallback(BT_STATUS_SUCCESS, 224911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson client_if0, hal_uuid); 225c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 226c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray EXPECT_EQ(1, callback_count); 227c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray ASSERT_TRUE(client.get() != nullptr); // Assert to terminate in case of error 228c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray EXPECT_EQ(BLE_STATUS_SUCCESS, status); 229bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_EQ(client_if0, client->GetInstanceId()); 23008f80ebd5c714364cb76cc4e4a93454b42ed5669Arman Uguray EXPECT_EQ(uuid0, client->GetAppIdentifier()); 231c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray EXPECT_EQ(uuid0, cb_uuid); 232c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 233c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray // The client should unregister itself when deleted. 234c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray EXPECT_CALL(*mock_handler_, UnregisterClient(client_if0)) 235c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray .Times(1) 236c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 237c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray client.reset(); 23860b0e8f7ef14b1c0bd0e6d86656cd912dd4c4221Jakub Pawlowski ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get()); 239c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 240c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray // |uuid1| fails. 241c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray int client_if1 = 3; 242c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray hal_uuid = uuid1.GetBlueDroid(); 243911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson fake_hal_gatt_iface_->NotifyRegisterClientCallback(BT_STATUS_FAIL, client_if1, 244911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson hal_uuid); 245c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray 246c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray EXPECT_EQ(2, callback_count); 247c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray ASSERT_TRUE(client.get() == nullptr); // Assert to terminate in case of error 248c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray EXPECT_EQ(BLE_STATUS_FAILURE, status); 249c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray EXPECT_EQ(uuid1, cb_uuid); 25012338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray} 25112338405e0d8d70573e650560ccc8e1ce7d8e8cdArman Uguray 252a6372e984aea35ffb451fca378046efbf280291cJakub PawlowskiMATCHER_P(BitEq, x, std::string(negation ? "isn't" : "is") + 253a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski " bitwise equal to " + ::testing::PrintToString(x)) { 254a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski static_assert(sizeof(x) == sizeof(arg), "Size mismatch"); 255a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski return std::memcmp(&arg, &x, sizeof(x)) == 0; 256a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski} 257a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski 258a6372e984aea35ffb451fca378046efbf280291cJakub PawlowskiTEST_F(LowEnergyClientPostRegisterTest, Connect) { 2599e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski const RawAddress kTestAddress = {{0x01, 0x02, 0x03, 0x0A, 0x0B, 0x0C}}; 260a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski const char kTestAddressStr[] = "01:02:03:0A:0B:0C"; 261a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski const bool kTestDirect = false; 262a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski const int connId = 12; 263a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski 264a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski TestDelegate delegate; 265a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski le_client_->SetDelegate(&delegate); 266a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski 267a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski // TODO(jpawlowski): NotifyConnectCallback should be called after returning 268a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski // success, fix it when it becomes important. 269a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski // These should succeed and result in a HAL call 270911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson EXPECT_CALL(*mock_handler_, 27196ac0a3c16a4a9f98169baf158bae16528cde79bJakub Pawlowski Connect(le_client_->GetInstanceId(), BitEq(kTestAddress), 272911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson kTestDirect, BT_TRANSPORT_LE)) 273a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski .Times(1) 2749e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski .WillOnce(DoAll(Invoke([&](int client_id, const RawAddress& bd_addr, 275911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bool is_direct, int transport) { 276911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson fake_hal_gatt_iface_->NotifyConnectCallback( 27796ac0a3c16a4a9f98169baf158bae16528cde79bJakub Pawlowski connId, BT_STATUS_SUCCESS, client_id, bd_addr); 278911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson }), 279911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson Return(BT_STATUS_SUCCESS))); 280a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski 281a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski EXPECT_TRUE(le_client_->Connect(kTestAddressStr, kTestDirect)); 282a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski EXPECT_EQ(1, delegate.connection_state_count()); 283a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski 284a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski // TODO(jpawlowski): same as above 285a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski // These should succeed and result in a HAL call 286a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski EXPECT_CALL(*mock_handler_, Disconnect(le_client_->GetInstanceId(), 28796ac0a3c16a4a9f98169baf158bae16528cde79bJakub Pawlowski BitEq(kTestAddress), connId)) 288a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski .Times(1) 289a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski .WillOnce(DoAll( 2909e030fde05352ec4385d7baf6cc2af89e95e039cJakub Pawlowski Invoke([&](int client_id, const RawAddress& bd_addr, int connId) { 291911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson fake_hal_gatt_iface_->NotifyDisconnectCallback( 29296ac0a3c16a4a9f98169baf158bae16528cde79bJakub Pawlowski connId, BT_STATUS_SUCCESS, client_id, bd_addr); 293911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson }), 294911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson Return(BT_STATUS_SUCCESS))); 295a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski 296a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski EXPECT_TRUE(le_client_->Disconnect(kTestAddressStr)); 297a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski EXPECT_EQ(2, delegate.connection_state_count()); 298a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski 299a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski le_client_->SetDelegate(nullptr); 300a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get()); 301a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski} 302a6372e984aea35ffb451fca378046efbf280291cJakub Pawlowski 303c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray} // namespace 304c2fc0f287f4dfaf206a51856b8d5dfa923af3c05Arman Uguray} // namespace bluetooth 305