150a31545d2d20d92d161c51195b653eafd164025Arman Uguray//
25b790feeeb211c42bf78ca3ae9c26aa30e516765Jakub Pawlowski//  Copyright 2015 Google, Inc.
350a31545d2d20d92d161c51195b653eafd164025Arman Uguray//
450a31545d2d20d92d161c51195b653eafd164025Arman Uguray//  Licensed under the Apache License, Version 2.0 (the "License");
550a31545d2d20d92d161c51195b653eafd164025Arman Uguray//  you may not use this file except in compliance with the License.
650a31545d2d20d92d161c51195b653eafd164025Arman Uguray//  You may obtain a copy of the License at:
750a31545d2d20d92d161c51195b653eafd164025Arman Uguray//
850a31545d2d20d92d161c51195b653eafd164025Arman Uguray//  http://www.apache.org/licenses/LICENSE-2.0
950a31545d2d20d92d161c51195b653eafd164025Arman Uguray//
1050a31545d2d20d92d161c51195b653eafd164025Arman Uguray//  Unless required by applicable law or agreed to in writing, software
1150a31545d2d20d92d161c51195b653eafd164025Arman Uguray//  distributed under the License is distributed on an "AS IS" BASIS,
1250a31545d2d20d92d161c51195b653eafd164025Arman Uguray//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1350a31545d2d20d92d161c51195b653eafd164025Arman Uguray//  See the License for the specific language governing permissions and
1450a31545d2d20d92d161c51195b653eafd164025Arman Uguray//  limitations under the License.
1550a31545d2d20d92d161c51195b653eafd164025Arman Uguray//
1650a31545d2d20d92d161c51195b653eafd164025Arman Uguray
1750a31545d2d20d92d161c51195b653eafd164025Arman Uguray#include <base/macros.h>
1850a31545d2d20d92d161c51195b653eafd164025Arman Uguray#include <gmock/gmock.h>
1950a31545d2d20d92d161c51195b653eafd164025Arman Uguray#include <gtest/gtest.h>
2050a31545d2d20d92d161c51195b653eafd164025Arman Uguray
2150a31545d2d20d92d161c51195b653eafd164025Arman Uguray#include "service/gatt_client.h"
2250a31545d2d20d92d161c51195b653eafd164025Arman Uguray#include "service/hal/fake_bluetooth_gatt_interface.h"
2350a31545d2d20d92d161c51195b653eafd164025Arman Uguray
2450a31545d2d20d92d161c51195b653eafd164025Arman Ugurayusing ::testing::_;
2550a31545d2d20d92d161c51195b653eafd164025Arman Ugurayusing ::testing::Return;
2650a31545d2d20d92d161c51195b653eafd164025Arman Uguray
2750a31545d2d20d92d161c51195b653eafd164025Arman Uguraynamespace bluetooth {
2850a31545d2d20d92d161c51195b653eafd164025Arman Uguraynamespace {
2950a31545d2d20d92d161c51195b653eafd164025Arman Uguray
3050a31545d2d20d92d161c51195b653eafd164025Arman Ugurayclass MockGattHandler
3150a31545d2d20d92d161c51195b653eafd164025Arman Uguray    : public hal::FakeBluetoothGattInterface::TestClientHandler {
3250a31545d2d20d92d161c51195b653eafd164025Arman Uguray public:
3350a31545d2d20d92d161c51195b653eafd164025Arman Uguray  MockGattHandler() = default;
3450a31545d2d20d92d161c51195b653eafd164025Arman Uguray  ~MockGattHandler() override = default;
3550a31545d2d20d92d161c51195b653eafd164025Arman Uguray
36819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski  MOCK_METHOD1(RegisterClient, bt_status_t(const bluetooth::Uuid&));
3750a31545d2d20d92d161c51195b653eafd164025Arman Uguray  MOCK_METHOD1(UnregisterClient, bt_status_t(int));
383f6aa07299fd9db634274fd22821b349f18b5e0fArman Uguray  MOCK_METHOD1(Scan, bt_status_t(bool));
39a484a888196ddf8bcbf1ad3226d6451bc735a94bJakub Pawlowski  MOCK_METHOD4(Connect, bt_status_t(int, const RawAddress&, bool, int));
40a484a888196ddf8bcbf1ad3226d6451bc735a94bJakub Pawlowski  MOCK_METHOD3(Disconnect, bt_status_t(int, const RawAddress&, int));
4150a31545d2d20d92d161c51195b653eafd164025Arman Uguray
4250a31545d2d20d92d161c51195b653eafd164025Arman Uguray private:
4350a31545d2d20d92d161c51195b653eafd164025Arman Uguray  DISALLOW_COPY_AND_ASSIGN(MockGattHandler);
4450a31545d2d20d92d161c51195b653eafd164025Arman Uguray};
4550a31545d2d20d92d161c51195b653eafd164025Arman Uguray
4650a31545d2d20d92d161c51195b653eafd164025Arman Ugurayclass GattClientTest : public ::testing::Test {
4750a31545d2d20d92d161c51195b653eafd164025Arman Uguray public:
4850a31545d2d20d92d161c51195b653eafd164025Arman Uguray  GattClientTest() = default;
4950a31545d2d20d92d161c51195b653eafd164025Arman Uguray  ~GattClientTest() override = default;
5050a31545d2d20d92d161c51195b653eafd164025Arman Uguray
5150a31545d2d20d92d161c51195b653eafd164025Arman Uguray  void SetUp() override {
5250a31545d2d20d92d161c51195b653eafd164025Arman Uguray    // Only set |mock_handler_| if a previous test case hasn't set it.
53911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (!mock_handler_) mock_handler_.reset(new MockGattHandler());
5450a31545d2d20d92d161c51195b653eafd164025Arman Uguray
5550a31545d2d20d92d161c51195b653eafd164025Arman Uguray    fake_hal_gatt_iface_ = new hal::FakeBluetoothGattInterface(
56911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        nullptr, nullptr,
5750a31545d2d20d92d161c51195b653eafd164025Arman Uguray        std::static_pointer_cast<
5850a31545d2d20d92d161c51195b653eafd164025Arman Uguray            hal::FakeBluetoothGattInterface::TestClientHandler>(mock_handler_),
5950a31545d2d20d92d161c51195b653eafd164025Arman Uguray        nullptr);
6050a31545d2d20d92d161c51195b653eafd164025Arman Uguray    hal::BluetoothGattInterface::InitializeForTesting(fake_hal_gatt_iface_);
6150a31545d2d20d92d161c51195b653eafd164025Arman Uguray
6250a31545d2d20d92d161c51195b653eafd164025Arman Uguray    factory_.reset(new GattClientFactory());
6350a31545d2d20d92d161c51195b653eafd164025Arman Uguray  }
6450a31545d2d20d92d161c51195b653eafd164025Arman Uguray
6550a31545d2d20d92d161c51195b653eafd164025Arman Uguray  void TearDown() override {
6650a31545d2d20d92d161c51195b653eafd164025Arman Uguray    factory_.reset();
6750a31545d2d20d92d161c51195b653eafd164025Arman Uguray    hal::BluetoothGattInterface::CleanUp();
6850a31545d2d20d92d161c51195b653eafd164025Arman Uguray  }
6950a31545d2d20d92d161c51195b653eafd164025Arman Uguray
7050a31545d2d20d92d161c51195b653eafd164025Arman Uguray protected:
7150a31545d2d20d92d161c51195b653eafd164025Arman Uguray  hal::FakeBluetoothGattInterface* fake_hal_gatt_iface_;
7250a31545d2d20d92d161c51195b653eafd164025Arman Uguray  std::shared_ptr<MockGattHandler> mock_handler_;
7350a31545d2d20d92d161c51195b653eafd164025Arman Uguray  std::unique_ptr<GattClientFactory> factory_;
7450a31545d2d20d92d161c51195b653eafd164025Arman Uguray
7550a31545d2d20d92d161c51195b653eafd164025Arman Uguray private:
7650a31545d2d20d92d161c51195b653eafd164025Arman Uguray  DISALLOW_COPY_AND_ASSIGN(GattClientTest);
7750a31545d2d20d92d161c51195b653eafd164025Arman Uguray};
7850a31545d2d20d92d161c51195b653eafd164025Arman Uguray
79bb18c41ffa0370d4eb0c4a15904b114355606466Arman UgurayTEST_F(GattClientTest, RegisterInstance) {
8050a31545d2d20d92d161c51195b653eafd164025Arman Uguray  EXPECT_CALL(*mock_handler_, RegisterClient(_))
8150a31545d2d20d92d161c51195b653eafd164025Arman Uguray      .Times(2)
8250a31545d2d20d92d161c51195b653eafd164025Arman Uguray      .WillOnce(Return(BT_STATUS_FAIL))
8350a31545d2d20d92d161c51195b653eafd164025Arman Uguray      .WillOnce(Return(BT_STATUS_SUCCESS));
8450a31545d2d20d92d161c51195b653eafd164025Arman Uguray
8550a31545d2d20d92d161c51195b653eafd164025Arman Uguray  // These will be asynchronously populated with a result when the callback
8650a31545d2d20d92d161c51195b653eafd164025Arman Uguray  // executes.
8750a31545d2d20d92d161c51195b653eafd164025Arman Uguray  BLEStatus status = BLE_STATUS_SUCCESS;
88819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski  Uuid cb_uuid;
8950a31545d2d20d92d161c51195b653eafd164025Arman Uguray  std::unique_ptr<GattClient> client;
9050a31545d2d20d92d161c51195b653eafd164025Arman Uguray  int callback_count = 0;
9150a31545d2d20d92d161c51195b653eafd164025Arman Uguray
92819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski  auto callback = [&](BLEStatus in_status, const Uuid& uuid,
93bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray                      std::unique_ptr<BluetoothInstance> in_client) {
94911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    status = in_status;
95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    cb_uuid = uuid;
96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    client = std::unique_ptr<GattClient>(
97911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        static_cast<GattClient*>(in_client.release()));
98911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    callback_count++;
99911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  };
10050a31545d2d20d92d161c51195b653eafd164025Arman Uguray
101819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski  Uuid uuid0 = Uuid::GetRandom();
10250a31545d2d20d92d161c51195b653eafd164025Arman Uguray
10350a31545d2d20d92d161c51195b653eafd164025Arman Uguray  // HAL returns failure.
104bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  EXPECT_FALSE(factory_->RegisterInstance(uuid0, callback));
10550a31545d2d20d92d161c51195b653eafd164025Arman Uguray  EXPECT_EQ(0, callback_count);
10650a31545d2d20d92d161c51195b653eafd164025Arman Uguray
10750a31545d2d20d92d161c51195b653eafd164025Arman Uguray  // HAL returns success.
108bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  EXPECT_TRUE(factory_->RegisterInstance(uuid0, callback));
10950a31545d2d20d92d161c51195b653eafd164025Arman Uguray  EXPECT_EQ(0, callback_count);
11050a31545d2d20d92d161c51195b653eafd164025Arman Uguray
111819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski  // Calling twice with the same Uuid should fail with no additional call into
11250a31545d2d20d92d161c51195b653eafd164025Arman Uguray  // the stack.
113bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  EXPECT_FALSE(factory_->RegisterInstance(uuid0, callback));
11450a31545d2d20d92d161c51195b653eafd164025Arman Uguray
11550a31545d2d20d92d161c51195b653eafd164025Arman Uguray  testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
11650a31545d2d20d92d161c51195b653eafd164025Arman Uguray
117819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski  // Call with a different Uuid while one is pending.
118819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski  Uuid uuid1 = Uuid::GetRandom();
11950a31545d2d20d92d161c51195b653eafd164025Arman Uguray  EXPECT_CALL(*mock_handler_, RegisterClient(_))
12050a31545d2d20d92d161c51195b653eafd164025Arman Uguray      .Times(1)
12150a31545d2d20d92d161c51195b653eafd164025Arman Uguray      .WillOnce(Return(BT_STATUS_SUCCESS));
122bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  EXPECT_TRUE(factory_->RegisterInstance(uuid1, callback));
12350a31545d2d20d92d161c51195b653eafd164025Arman Uguray
124819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski  // Trigger callback with an unknown Uuid. This should get ignored.
125819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski  Uuid uuid2 = Uuid::GetRandom();
126819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski  fake_hal_gatt_iface_->NotifyRegisterClientCallback(0, 0, uuid2);
12750a31545d2d20d92d161c51195b653eafd164025Arman Uguray  EXPECT_EQ(0, callback_count);
12850a31545d2d20d92d161c51195b653eafd164025Arman Uguray
12950a31545d2d20d92d161c51195b653eafd164025Arman Uguray  // |uuid0| succeeds.
13050a31545d2d20d92d161c51195b653eafd164025Arman Uguray  int client_id0 = 2;  // Pick something that's not 0.
131911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  fake_hal_gatt_iface_->NotifyRegisterClientCallback(BT_STATUS_SUCCESS,
132819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski                                                     client_id0, uuid0);
13350a31545d2d20d92d161c51195b653eafd164025Arman Uguray
13450a31545d2d20d92d161c51195b653eafd164025Arman Uguray  EXPECT_EQ(1, callback_count);
13550a31545d2d20d92d161c51195b653eafd164025Arman Uguray  ASSERT_TRUE(client.get() != nullptr);  // Assert to terminate in case of error
13650a31545d2d20d92d161c51195b653eafd164025Arman Uguray  EXPECT_EQ(BLE_STATUS_SUCCESS, status);
137bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray  EXPECT_EQ(client_id0, client->GetInstanceId());
13850a31545d2d20d92d161c51195b653eafd164025Arman Uguray  EXPECT_EQ(uuid0, client->GetAppIdentifier());
13950a31545d2d20d92d161c51195b653eafd164025Arman Uguray  EXPECT_EQ(uuid0, cb_uuid);
14050a31545d2d20d92d161c51195b653eafd164025Arman Uguray
14150a31545d2d20d92d161c51195b653eafd164025Arman Uguray  // The client should unregister itself when deleted.
14250a31545d2d20d92d161c51195b653eafd164025Arman Uguray  EXPECT_CALL(*mock_handler_, UnregisterClient(client_id0))
14350a31545d2d20d92d161c51195b653eafd164025Arman Uguray      .Times(1)
14450a31545d2d20d92d161c51195b653eafd164025Arman Uguray      .WillOnce(Return(BT_STATUS_SUCCESS));
14550a31545d2d20d92d161c51195b653eafd164025Arman Uguray  client.reset();
14650a31545d2d20d92d161c51195b653eafd164025Arman Uguray  testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
14750a31545d2d20d92d161c51195b653eafd164025Arman Uguray
14850a31545d2d20d92d161c51195b653eafd164025Arman Uguray  // |uuid1| fails.
14950a31545d2d20d92d161c51195b653eafd164025Arman Uguray  int client_id1 = 3;
150911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  fake_hal_gatt_iface_->NotifyRegisterClientCallback(BT_STATUS_FAIL, client_id1,
151819e2ecb84a22d6e03ec9ed67b3260c0dd7e8abaJakub Pawlowski                                                     uuid1);
15250a31545d2d20d92d161c51195b653eafd164025Arman Uguray
15350a31545d2d20d92d161c51195b653eafd164025Arman Uguray  EXPECT_EQ(2, callback_count);
15450a31545d2d20d92d161c51195b653eafd164025Arman Uguray  ASSERT_TRUE(client.get() == nullptr);  // Assert to terminate in case of error
15550a31545d2d20d92d161c51195b653eafd164025Arman Uguray  EXPECT_EQ(BLE_STATUS_FAILURE, status);
15650a31545d2d20d92d161c51195b653eafd164025Arman Uguray  EXPECT_EQ(uuid1, cb_uuid);
15750a31545d2d20d92d161c51195b653eafd164025Arman Uguray}
15850a31545d2d20d92d161c51195b653eafd164025Arman Uguray
15950a31545d2d20d92d161c51195b653eafd164025Arman Uguray}  // namespace
16050a31545d2d20d92d161c51195b653eafd164025Arman Uguray}  // namespace bluetooth
161