#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "services/device/geolocation/location_provider_manager.h"
#include <memory>
#include <utility>
#include "base/containers/span.h"
#include "base/functional/bind.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/ranges/algorithm.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "services/device/geolocation/fake_location_provider.h"
#include "services/device/geolocation/fake_position_cache.h"
#include "services/device/public/cpp/device_features.h"
#include "services/device/public/cpp/geolocation/geoposition.h"
#include "services/device/public/cpp/geolocation/location_provider.h"
#include "services/device/public/mojom/geoposition.mojom.h"
#include "services/network/test/test_shared_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
NiceMock;
namespace device {
namespace {
std::unique_ptr<LocationProvider> NullLocationProvider() { … }
class MockLocationObserver { … };
void SetPositionFix(FakeLocationProvider* provider,
double latitude,
double longitude,
double accuracy) { … }
void SetErrorPosition(FakeLocationProvider* provider,
mojom::GeopositionErrorCode error_code) { … }
void SetReferencePosition(FakeLocationProvider* provider) { … }
}
class TestingLocationProviderManager : public LocationProviderManager { … };
class GeolocationLocationProviderManagerTest : public testing::Test { … };
TEST_F(GeolocationLocationProviderManagerTest, CreateDestroy) { … }
TEST_F(GeolocationLocationProviderManagerTest, OnPermissionGranted) { … }
#if !BUILDFLAG(IS_ANDROID)
TEST_F(GeolocationLocationProviderManagerTest, NetworkOnly) { … }
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID)
TEST_F(GeolocationLocationProviderManagerTest, PlatformOnly) {
ASSERT_TRUE(
SetExperimentMode(mojom::LocationProviderManagerMode::kPlatformOnly));
InitializeLocationProviderManager(base::BindRepeating(&NullLocationProvider),
url_loader_factory_);
ASSERT_TRUE(location_provider_manager_);
EXPECT_FALSE(network_location_provider());
EXPECT_FALSE(system_location_provider());
location_provider_manager_->StartProvider(false);
EXPECT_FALSE(network_location_provider());
ASSERT_TRUE(system_location_provider());
EXPECT_EQ(mojom::GeolocationDiagnostics::ProviderState::kLowAccuracy,
system_location_provider()->state());
EXPECT_FALSE(observer_->last_result());
SetReferencePosition(system_location_provider());
ASSERT_TRUE(observer_->last_result());
if (observer_->last_result()->is_position()) {
ASSERT_TRUE(system_location_provider()->GetPosition());
EXPECT_EQ(
system_location_provider()->GetPosition()->get_position()->latitude,
observer_->last_result()->get_position()->latitude);
}
EXPECT_FALSE(system_location_provider()->is_permission_granted());
EXPECT_FALSE(location_provider_manager_->HasPermissionBeenGrantedForTest());
location_provider_manager_->OnPermissionGranted();
EXPECT_TRUE(location_provider_manager_->HasPermissionBeenGrantedForTest());
EXPECT_TRUE(system_location_provider()->is_permission_granted());
SetErrorPosition(system_location_provider(),
mojom::GeopositionErrorCode::kPositionUnavailable);
EXPECT_TRUE(system_location_provider()->GetPosition()->is_error());
EXPECT_TRUE(observer_->last_result()->is_error());
EXPECT_EQ(system_location_provider()->GetPosition()->get_error(),
observer_->last_result()->get_error());
}
#endif
TEST_F(GeolocationLocationProviderManagerTest, CustomSystemProviderOnly) { … }
#if !BUILDFLAG(IS_ANDROID)
TEST_F(GeolocationLocationProviderManagerTest, SetObserverOptions) { … }
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
TEST_F(GeolocationLocationProviderManagerTest, HybridPlatformFallback) {
ASSERT_TRUE(
SetExperimentMode(mojom::LocationProviderManagerMode::kHybridPlatform));
InitializeLocationProviderManager(base::BindRepeating(&NullLocationProvider),
url_loader_factory_);
ASSERT_TRUE(location_provider_manager_);
EXPECT_FALSE(network_location_provider());
EXPECT_FALSE(system_location_provider());
location_provider_manager_->StartProvider(false);
EXPECT_FALSE(network_location_provider());
ASSERT_TRUE(system_location_provider());
EXPECT_EQ(mojom::GeolocationDiagnostics::ProviderState::kLowAccuracy,
system_location_provider()->state());
EXPECT_FALSE(observer_->last_result());
SetReferencePosition(system_location_provider());
ASSERT_TRUE(observer_->last_result());
if (observer_->last_result()->is_position()) {
ASSERT_TRUE(system_location_provider()->GetPosition());
EXPECT_EQ(
system_location_provider()->GetPosition()->get_position()->latitude,
observer_->last_result()->get_position()->latitude);
}
SetErrorPosition(system_location_provider(),
mojom::GeopositionErrorCode::kPositionUnavailable);
EXPECT_TRUE(system_location_provider()->GetPosition()->is_error());
EXPECT_TRUE(observer_->last_result()->is_error());
EXPECT_EQ(system_location_provider()->GetPosition()->get_error(),
observer_->last_result()->get_error());
EXPECT_FALSE(network_location_provider());
}
#endif
}