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