// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/quick_pair/feature_status_tracker/fast_pair_enabled_provider.h"
#include <memory>
#include "ash/constants/ash_features.h"
#include "ash/quick_pair/common/fake_bluetooth_adapter.h"
#include "ash/quick_pair/feature_status_tracker/bluetooth_enabled_provider.h"
#include "ash/quick_pair/feature_status_tracker/fast_pair_pref_enabled_provider.h"
#include "ash/quick_pair/feature_status_tracker/logged_in_user_enabled_provider.h"
#include "ash/quick_pair/feature_status_tracker/mock_bluetooth_enabled_provider.h"
#include "ash/quick_pair/feature_status_tracker/mock_fast_pair_pref_enabled_provider.h"
#include "ash/quick_pair/feature_status_tracker/mock_google_api_key_availability_provider.h"
#include "ash/quick_pair/feature_status_tracker/mock_logged_in_user_enabled_provider.h"
#include "ash/quick_pair/feature_status_tracker/mock_scanning_enabled_provider.h"
#include "ash/quick_pair/feature_status_tracker/mock_screen_state_enabled_provider.h"
#include "ash/quick_pair/feature_status_tracker/screen_state_enabled_provider.h"
#include "ash/test/ash_test_base.h"
#include "base/functional/callback.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "testing/gtest/include/gtest/gtest-param-test.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
constexpr int kNumFastPairEnabledProviderArgs = 6;
} // namespace
namespace ash::quick_pair {
class FastPairEnabledProviderTest : public AshTestBase {
public:
void SetUp() override {
AshTestBase::SetUp();
adapter_ = base::MakeRefCounted<FakeBluetoothAdapter>();
device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_);
}
protected:
scoped_refptr<FakeBluetoothAdapter> adapter_;
};
TEST_F(FastPairEnabledProviderTest, ProviderCallbackIsInvokedOnBTChanges) {
base::test::ScopedFeatureList feature_list{features::kFastPair};
base::MockCallback<base::RepeatingCallback<void(bool)>> callback;
EXPECT_CALL(callback, Run(true));
auto* fast_pair_pref_enabled_provider = new MockFastPairPrefEnabledProvider();
ON_CALL(*fast_pair_pref_enabled_provider, is_enabled)
.WillByDefault(testing::Return(true));
auto* logged_in_user_enabled_provider = new MockLoggedInUserEnabledProvider();
ON_CALL(*logged_in_user_enabled_provider, is_enabled)
.WillByDefault(testing::Return(true));
auto* screen_state_enabled_provider = new MockScreenStateEnabledProvider();
ON_CALL(*screen_state_enabled_provider, is_enabled)
.WillByDefault(testing::Return(true));
auto* google_api_key_availability_provider =
new MockGoogleApiKeyAvailabilityProvider();
ON_CALL(*google_api_key_availability_provider, is_enabled)
.WillByDefault(testing::Return(true));
auto* scanning_enabled_provider = new MockScanningEnabledProvider();
ON_CALL(*scanning_enabled_provider, is_enabled)
.WillByDefault(testing::Return(true));
auto provider = std::make_unique<FastPairEnabledProvider>(
std::make_unique<BluetoothEnabledProvider>(),
base::WrapUnique(fast_pair_pref_enabled_provider),
base::WrapUnique(logged_in_user_enabled_provider),
base::WrapUnique(screen_state_enabled_provider),
base::WrapUnique(google_api_key_availability_provider),
base::WrapUnique(scanning_enabled_provider));
provider->SetCallback(callback.Get());
adapter_->SetBluetoothIsPowered(true);
}
TEST_F(FastPairEnabledProviderTest, IsEnabledWhenExpected) {
base::test::ScopedFeatureList feature_list;
const base::flat_map<base::test::FeatureRef, bool> feature_states{
{features::kFastPair, true},
{features::kFastPairSoftwareScanningSupport, true}};
feature_list.InitWithFeatureStates(feature_states);
auto* bluetooth_enabled_provider = new MockBluetoothEnabledProvider();
ON_CALL(*bluetooth_enabled_provider, is_enabled)
.WillByDefault(testing::Return(true));
auto* fast_pair_pref_enabled_provider = new MockFastPairPrefEnabledProvider();
ON_CALL(*fast_pair_pref_enabled_provider, is_enabled)
.WillByDefault(testing::Return(true));
auto* logged_in_user_enabled_provider = new MockLoggedInUserEnabledProvider();
ON_CALL(*logged_in_user_enabled_provider, is_enabled)
.WillByDefault(testing::Return(true));
auto* screen_state_enabled_provider = new MockScreenStateEnabledProvider();
ON_CALL(*screen_state_enabled_provider, is_enabled)
.WillByDefault(testing::Return(true));
auto* google_api_key_availability_provider =
new MockGoogleApiKeyAvailabilityProvider();
ON_CALL(*google_api_key_availability_provider, is_enabled)
.WillByDefault(testing::Return(true));
auto* scanning_enabled_provider = new MockScanningEnabledProvider();
ON_CALL(*scanning_enabled_provider, is_enabled)
.WillByDefault(testing::Return(true));
auto provider = std::make_unique<FastPairEnabledProvider>(
std::unique_ptr<BluetoothEnabledProvider>(bluetooth_enabled_provider),
std::unique_ptr<FastPairPrefEnabledProvider>(
fast_pair_pref_enabled_provider),
std::unique_ptr<LoggedInUserEnabledProvider>(
logged_in_user_enabled_provider),
std::unique_ptr<ScreenStateEnabledProvider>(
screen_state_enabled_provider),
base::WrapUnique(google_api_key_availability_provider),
base::WrapUnique(scanning_enabled_provider));
EXPECT_TRUE(provider->is_enabled());
}
class FastPairEnabledProviderTestNoCrashOnNullInputs
: public FastPairEnabledProviderTest,
public testing::WithParamInterface<size_t> {};
TEST_P(FastPairEnabledProviderTestNoCrashOnNullInputs, NoCrashOnNullInputs) {
base::test::ScopedFeatureList feature_list;
const base::flat_map<base::test::FeatureRef, bool> feature_states{
{features::kFastPair, true},
{features::kFastPairSoftwareScanningSupport, true}};
feature_list.InitWithFeatureStates(feature_states);
size_t args_mask = GetParam();
bool is_bluetooth_provider_nonnull = args_mask & 1;
bool is_fast_pair_pref_nonnull = args_mask & 2;
bool is_user_enabled_provider_nonnull = args_mask & 4;
bool is_screen_enabled_provider_nonnull = args_mask & 8;
bool is_api_provider_nonnull = args_mask & 16;
bool is_scanning_provider_nonnull = args_mask & 32;
std::unique_ptr<BluetoothEnabledProvider> bluetooth_enabled_provider;
if (is_bluetooth_provider_nonnull) {
bluetooth_enabled_provider = std::make_unique<BluetoothEnabledProvider>();
}
MockFastPairPrefEnabledProvider* fast_pair_pref_enabled_provider = nullptr;
if (is_fast_pair_pref_nonnull) {
fast_pair_pref_enabled_provider = new MockFastPairPrefEnabledProvider();
}
MockLoggedInUserEnabledProvider* logged_in_user_enabled_provider = nullptr;
if (is_user_enabled_provider_nonnull) {
logged_in_user_enabled_provider = new MockLoggedInUserEnabledProvider();
}
MockScreenStateEnabledProvider* screen_state_enabled_provider = nullptr;
if (is_screen_enabled_provider_nonnull) {
screen_state_enabled_provider = new MockScreenStateEnabledProvider();
}
MockGoogleApiKeyAvailabilityProvider* google_api_key_availability_provider =
nullptr;
if (is_api_provider_nonnull) {
google_api_key_availability_provider =
new MockGoogleApiKeyAvailabilityProvider();
}
MockScanningEnabledProvider* scanning_enabled_provider = nullptr;
if (is_scanning_provider_nonnull) {
scanning_enabled_provider = new MockScanningEnabledProvider();
}
std::unique_ptr<FastPairEnabledProvider> fast_pair_enabled_provider =
std::make_unique<FastPairEnabledProvider>(
std::move(bluetooth_enabled_provider),
base::WrapUnique(fast_pair_pref_enabled_provider),
base::WrapUnique(logged_in_user_enabled_provider),
base::WrapUnique(screen_state_enabled_provider),
base::WrapUnique(google_api_key_availability_provider),
base::WrapUnique(scanning_enabled_provider));
fast_pair_enabled_provider->is_enabled();
}
INSTANTIATE_TEST_SUITE_P(
FastPairEnabledProviderTestNoCrashOnNullInputs,
FastPairEnabledProviderTestNoCrashOnNullInputs,
testing::Range<size_t>(0, 1 << kNumFastPairEnabledProviderArgs));
} // namespace ash::quick_pair