| // |
| // Copyright (C) 2015 Google, Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at: |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| |
| #include <base/macros.h> |
| #include <gtest/gtest.h> |
| |
| #include "service/adapter.h" |
| #include "service/common/bluetooth/util/address_helper.h" |
| #include "service/hal/fake_bluetooth_gatt_interface.h" |
| #include "service/hal/fake_bluetooth_interface.h" |
| |
| namespace bluetooth { |
| namespace { |
| |
| class AdapterTest : public ::testing::Test { |
| public: |
| AdapterTest() = default; |
| ~AdapterTest() override = default; |
| |
| void SetUp() override { |
| fake_hal_manager_ = hal::FakeBluetoothInterface::GetManager(); |
| fake_hal_iface_ = new hal::FakeBluetoothInterface(); |
| hal::BluetoothInterface::InitializeForTesting(fake_hal_iface_); |
| |
| // Initialize GATT interface with default handlers. |
| hal::BluetoothGattInterface::InitializeForTesting( |
| new hal::FakeBluetoothGattInterface(nullptr, nullptr)); |
| |
| adapter_ = Adapter::Create(); |
| } |
| |
| void TearDown() override { |
| adapter_.reset(); |
| hal::BluetoothGattInterface::CleanUp(); |
| hal::BluetoothInterface::CleanUp(); |
| } |
| |
| protected: |
| hal::FakeBluetoothInterface* fake_hal_iface_; |
| hal::FakeBluetoothInterface::Manager* fake_hal_manager_; |
| std::unique_ptr<Adapter> adapter_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(AdapterTest); |
| }; |
| |
| class TestObserver final : public bluetooth::Adapter::Observer { |
| public: |
| TestObserver(bluetooth::Adapter* adapter) |
| : adapter_(adapter), |
| prev_state_(bluetooth::ADAPTER_STATE_INVALID), |
| cur_state_(bluetooth::ADAPTER_STATE_INVALID), |
| last_device_connected_state_(false) { |
| CHECK(adapter_); |
| adapter_->AddObserver(this); |
| } |
| |
| ~TestObserver() override { |
| adapter_->RemoveObserver(this); |
| } |
| |
| bluetooth::AdapterState prev_state() const { return prev_state_; } |
| bluetooth::AdapterState cur_state() const { return cur_state_; } |
| |
| std::string last_connection_state_address() const { |
| return last_connection_state_address_; |
| } |
| |
| bool last_device_connected_state() const { |
| return last_device_connected_state_; |
| } |
| |
| // bluetooth::Adapter::Observer override: |
| void OnAdapterStateChanged(bluetooth::Adapter* adapter, |
| bluetooth::AdapterState prev_state, |
| bluetooth::AdapterState new_state) override { |
| ASSERT_EQ(adapter_, adapter); |
| prev_state_ = prev_state; |
| cur_state_ = new_state; |
| } |
| |
| void OnDeviceConnectionStateChanged( |
| Adapter* adapter, |
| const std::string& device_address, |
| bool connected) override { |
| ASSERT_EQ(adapter_, adapter); |
| last_connection_state_address_ = device_address; |
| last_device_connected_state_ = connected; |
| } |
| |
| private: |
| bluetooth::Adapter* adapter_; |
| bluetooth::AdapterState prev_state_, cur_state_; |
| std::string last_connection_state_address_; |
| bool last_device_connected_state_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TestObserver); |
| }; |
| |
| TEST_F(AdapterTest, IsEnabled) { |
| EXPECT_FALSE(adapter_->IsEnabled()); |
| |
| fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_ON); |
| EXPECT_TRUE(adapter_->IsEnabled()); |
| |
| fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_OFF); |
| EXPECT_FALSE(adapter_->IsEnabled()); |
| } |
| |
| TEST_F(AdapterTest, Enable) { |
| TestObserver observer(adapter_.get()); |
| |
| EXPECT_FALSE(adapter_->IsEnabled()); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, adapter_->GetState()); |
| |
| // Enable fails at HAL level |
| EXPECT_FALSE(adapter_->Enable(false)); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, adapter_->GetState()); |
| |
| // Enable success |
| fake_hal_manager_->enable_succeed = true; |
| EXPECT_TRUE(adapter_->Enable(false)); |
| |
| // Should have received a state update. |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, observer.prev_state()); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_ON, observer.cur_state()); |
| |
| // Enable fails because not disabled |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_ON, adapter_->GetState()); |
| EXPECT_FALSE(adapter_->Enable(false)); |
| |
| // Adapter state updates properly |
| fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_ON); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, adapter_->GetState()); |
| |
| // Should have received a state update. |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_ON, observer.prev_state()); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.cur_state()); |
| |
| // Enable fails because already enabled |
| EXPECT_FALSE(adapter_->Enable(false)); |
| } |
| |
| TEST_F(AdapterTest, Disable) { |
| TestObserver observer(adapter_.get()); |
| |
| fake_hal_manager_->disable_succeed = true; |
| EXPECT_FALSE(adapter_->IsEnabled()); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, adapter_->GetState()); |
| |
| // Disable fails because already disabled |
| EXPECT_FALSE(adapter_->Disable()); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, adapter_->GetState()); |
| |
| // Disable success |
| fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_ON); |
| |
| // Should have received a state update. |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, observer.prev_state()); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.cur_state()); |
| |
| EXPECT_TRUE(adapter_->Disable()); |
| |
| // Should have received a state update. |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.prev_state()); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_OFF, observer.cur_state()); |
| |
| // Disable fails because not enabled |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_OFF, adapter_->GetState()); |
| EXPECT_FALSE(adapter_->Disable()); |
| |
| fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_ON); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, adapter_->GetState()); |
| |
| // Should have received a state update. |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_OFF, observer.prev_state()); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.cur_state()); |
| |
| // Disable fails at HAL level |
| fake_hal_manager_->disable_succeed = false; |
| EXPECT_FALSE(adapter_->Disable()); |
| |
| // Should have received a state update. In this case we will receive two |
| // updates: one going from OFF to TURNING_OFF, and one going from TURNING_OFF |
| // back to ON since we failed to initiate the disable operation. |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_TURNING_OFF, observer.prev_state()); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.cur_state()); |
| |
| // Update state to OFF. Should receive a state update. |
| fake_hal_iface_->NotifyAdapterStateChanged(BT_STATE_OFF); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_ON, observer.prev_state()); |
| EXPECT_EQ(bluetooth::ADAPTER_STATE_OFF, observer.cur_state()); |
| } |
| |
| TEST_F(AdapterTest, GetName) { |
| EXPECT_EQ(bluetooth::Adapter::kDefaultName, adapter_->GetName()); |
| |
| const char kTestAdapterName[] = "Test Adapter Name"; |
| |
| fake_hal_iface_->NotifyAdapterNamePropertyChanged(kTestAdapterName); |
| EXPECT_EQ(kTestAdapterName, adapter_->GetName()); |
| } |
| |
| TEST_F(AdapterTest, SetName) { |
| bt_bdname_t hal_name; |
| |
| // Name too large. |
| EXPECT_FALSE(adapter_->SetName(std::string(sizeof(hal_name.name), 'a'))); |
| |
| // Valid length. |
| EXPECT_FALSE(adapter_->SetName("Test Name")); |
| fake_hal_manager_->set_property_succeed = true; |
| EXPECT_TRUE(adapter_->SetName("Test Name")); |
| } |
| |
| TEST_F(AdapterTest, GetAddress) { |
| EXPECT_EQ(bluetooth::Adapter::kDefaultAddress, adapter_->GetAddress()); |
| |
| const bt_bdaddr_t kTestAdapterInput = { |
| { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc } |
| }; |
| const char kTestAdapterAddressOutput[] = "12:34:56:78:9A:BC"; |
| |
| fake_hal_iface_->NotifyAdapterAddressPropertyChanged(&kTestAdapterInput); |
| EXPECT_EQ(kTestAdapterAddressOutput, adapter_->GetAddress()); |
| } |
| |
| TEST_F(AdapterTest, IsMultiAdvertisementSupported) { |
| EXPECT_FALSE(adapter_->IsMultiAdvertisementSupported()); |
| |
| bt_local_le_features_t features; |
| memset(&features, 0, sizeof(features)); |
| |
| features.max_adv_instance = 10; // Some high number. |
| fake_hal_iface_->NotifyAdapterLocalLeFeaturesPropertyChanged(&features); |
| EXPECT_TRUE(adapter_->IsMultiAdvertisementSupported()); |
| |
| features.max_adv_instance = 0; // Low number. |
| fake_hal_iface_->NotifyAdapterLocalLeFeaturesPropertyChanged(&features); |
| EXPECT_FALSE(adapter_->IsMultiAdvertisementSupported()); |
| } |
| |
| TEST_F(AdapterTest, IsDeviceConnected) { |
| const char kDeviceAddr[] = "12:34:56:78:9A:BC"; |
| TestObserver observer(adapter_.get()); |
| |
| EXPECT_FALSE(adapter_->IsDeviceConnected(kDeviceAddr)); |
| |
| bt_bdaddr_t hal_addr; |
| ASSERT_TRUE(util::BdAddrFromString(kDeviceAddr, &hal_addr)); |
| |
| // status != BT_STATUS_SUCCESS should be ignored |
| fake_hal_iface_->NotifyAclStateChangedCallback( |
| BT_STATUS_FAIL, hal_addr, BT_ACL_STATE_CONNECTED); |
| EXPECT_FALSE(adapter_->IsDeviceConnected(kDeviceAddr)); |
| EXPECT_TRUE(observer.last_connection_state_address().empty()); |
| EXPECT_FALSE(observer.last_device_connected_state()); |
| |
| // Connected |
| fake_hal_iface_->NotifyAclStateChangedCallback( |
| BT_STATUS_SUCCESS, hal_addr, BT_ACL_STATE_CONNECTED); |
| EXPECT_TRUE(adapter_->IsDeviceConnected(kDeviceAddr)); |
| EXPECT_EQ(kDeviceAddr, observer.last_connection_state_address()); |
| EXPECT_TRUE(observer.last_device_connected_state()); |
| |
| // Disconnected |
| fake_hal_iface_->NotifyAclStateChangedCallback( |
| BT_STATUS_SUCCESS, hal_addr, BT_ACL_STATE_DISCONNECTED); |
| EXPECT_FALSE(adapter_->IsDeviceConnected(kDeviceAddr)); |
| EXPECT_EQ(kDeviceAddr, observer.last_connection_state_address()); |
| EXPECT_FALSE(observer.last_device_connected_state()); |
| } |
| |
| } // namespace |
| } // namespace bluetooth |