#include "services/device/geolocation/geolocation_provider_impl.h"
#include <iterator>
#include <memory>
#include <utility>
#include "base/check.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/memory/singleton.h"
#include "base/notreached.h"
#include "base/ranges/algorithm.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/default_tick_clock.h"
#include "build/build_config.h"
#include "components/device_event_log/device_event_log.h"
#include "net/base/network_change_notifier.h"
#include "services/device/geolocation/location_provider_manager.h"
#include "services/device/geolocation/position_cache_impl.h"
#include "services/device/public/cpp/device_features.h"
#include "services/device/public/cpp/geolocation/geoposition.h"
#include "services/device/public/cpp/geolocation/location_system_permission_status.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#if BUILDFLAG(IS_ANDROID)
#include "base/android/jni_android.h"
#include "services/device/geolocation/geolocation_jni_headers/LocationProviderFactory_jni.h"
#endif
namespace device {
namespace {
base::LazyInstance<CustomLocationProviderCallback>::Leaky
g_custom_location_provider_callback = …;
base::LazyInstance<std::unique_ptr<network::PendingSharedURLLoaderFactory>>::
Leaky g_pending_url_loader_factory = …;
base::LazyInstance<std::string>::Leaky g_api_key = …;
GeolocationSystemPermissionManager* g_geolocation_system_permission_manager = …;
}
GeolocationProvider* GeolocationProvider::instance_for_testing_ = …;
GeolocationProvider* GeolocationProvider::GetInstance() { … }
void GeolocationProvider::SetInstanceForTesting(
GeolocationProvider* instance_for_testing) { … }
void GeolocationProviderImpl::SetGeolocationConfiguration(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
const std::string& api_key,
const CustomLocationProviderCallback& custom_location_provider_getter,
GeolocationSystemPermissionManager* geolocation_system_permission_manager,
bool use_gms_core_location_provider) { … }
void GeolocationProviderImpl::SetGeolocationSystemPermissionManagerForTesting(
GeolocationSystemPermissionManager* instance_for_testing) { … }
base::CallbackListSubscription
GeolocationProviderImpl::AddLocationUpdateCallback(
const LocationUpdateCallback& callback,
bool enable_high_accuracy) { … }
bool GeolocationProviderImpl::HighAccuracyLocationInUse() { … }
void GeolocationProviderImpl::OverrideLocationForTesting(
mojom::GeopositionResultPtr result) { … }
void GeolocationProviderImpl::OnLocationUpdate(
const LocationProvider* provider,
mojom::GeopositionResultPtr result) { … }
GeolocationProviderImpl* GeolocationProviderImpl::GetInstance() { … }
void GeolocationProviderImpl::BindGeolocationControlReceiver(
mojo::PendingReceiver<mojom::GeolocationControl> receiver) { … }
void GeolocationProviderImpl::BindGeolocationInternalsReceiver(
mojo::PendingReceiver<mojom::GeolocationInternals> receiver) { … }
void GeolocationProviderImpl::UserDidOptIntoLocationServices() { … }
GeolocationProviderImpl::GeolocationProviderImpl()
: … { … }
GeolocationProviderImpl::~GeolocationProviderImpl() { … }
void GeolocationProviderImpl::SetLocationProviderManagerForTesting(
std::unique_ptr<LocationProvider> location_provider_manager) { … }
bool GeolocationProviderImpl::OnGeolocationThread() const { … }
void GeolocationProviderImpl::OnClientsChanged() { … }
void GeolocationProviderImpl::OnInternalsUpdated() { … }
void GeolocationProviderImpl::OnNetworkLocationRequested(
std::vector<mojom::AccessPointDataPtr> request) { … }
void GeolocationProviderImpl::OnNetworkLocationReceived(
mojom::NetworkLocationResponsePtr response) { … }
void GeolocationProviderImpl::OnInternalsObserverDisconnected(
mojo::RemoteSetElementId element_id) { … }
void GeolocationProviderImpl::StopProviders() { … }
void GeolocationProviderImpl::StartProviders(bool enable_high_accuracy,
bool enable_diagnostics) { … }
void GeolocationProviderImpl::InformProvidersPermissionGranted() { … }
void GeolocationProviderImpl::NotifyClients(
mojom::GeopositionResultPtr result) { … }
void GeolocationProviderImpl::NotifyInternalsUpdated(
mojom::GeolocationDiagnosticsPtr diagnostics) { … }
void GeolocationProviderImpl::NotifyNetworkLocationRequested(
std::vector<mojom::AccessPointDataPtr> request) { … }
void GeolocationProviderImpl::NotifyNetworkLocationReceived(
mojom::NetworkLocationResponsePtr response) { … }
void GeolocationProviderImpl::Init() { … }
void GeolocationProviderImpl::CleanUp() { … }
void GeolocationProviderImpl::AddInternalsObserver(
mojo::PendingRemote<mojom::GeolocationInternalsObserver> observer,
AddInternalsObserverCallback callback) { … }
void GeolocationProviderImpl::SimulateInternalsUpdatedForTesting() { … }
mojom::GeolocationDiagnosticsPtr
GeolocationProviderImpl::EnableAndGetDiagnosticsOnGeolocationThread() { … }
void GeolocationProviderImpl::DisableDiagnosticsOnGeolocationThread() { … }
#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
void GeolocationProviderImpl::OnSystemPermissionUpdated(
LocationSystemPermissionStatus new_status) {
CHECK(main_task_runner_->BelongsToCurrentThread());
if (new_status == LocationSystemPermissionStatus::kAllowed) {
GEOLOCATION_LOG(DEBUG) << "New system permission state is kAllowed";
if (!high_accuracy_callbacks_.empty() || !low_accuracy_callbacks_.empty()) {
DoStartProvidersOnGeolocationThread();
}
} else if (new_status == LocationSystemPermissionStatus::kDenied) {
GEOLOCATION_LOG(DEBUG) << "New system permission state is kDenied";
NotifyClientsSystemPermissionDenied();
} else {
GEOLOCATION_LOG(DEBUG) << "New system permission state is kUndetermined";
NotifyClientsSystemPermissionDenied();
}
system_permission_status_ = new_status;
}
void GeolocationProviderImpl::NotifyClientsSystemPermissionDenied() {
CHECK(main_task_runner_->BelongsToCurrentThread());
auto error_result =
mojom::GeopositionResult::NewError(mojom::GeopositionError::New(
mojom::GeopositionErrorCode::kPermissionDenied,
kSystemPermissionDeniedErrorMessage, ""));
NotifyClients(std::move(error_result));
}
#endif
void GeolocationProviderImpl::DoStartProvidersOnGeolocationThread() { … }
}