#ifndef SERVICES_DEVICE_PUBLIC_CPP_GEOLOCATION_SYSTEM_GEOLOCATION_SOURCE_APPLE_H_
#define SERVICES_DEVICE_PUBLIC_CPP_GEOLOCATION_SYSTEM_GEOLOCATION_SOURCE_APPLE_H_
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/network_change_notifier.h"
#include "services/device/public/cpp/geolocation/geolocation_system_permission_manager.h"
#include "services/device/public/cpp/geolocation/system_geolocation_source.h"
@class CLLocationManager;
@class LocationManagerDelegate;
namespace device {
class COMPONENT_EXPORT(GEOLOCATION) SystemGeolocationSourceApple
: public SystemGeolocationSource,
public net::NetworkChangeNotifier::NetworkChangeObserver {
public:
static std::unique_ptr<GeolocationSystemPermissionManager>
CreateGeolocationSystemPermissionManager();
static bool IsWifiEnabled();
static void SetWifiStatusForTesting(bool mock_wifi_status) {
mock_wifi_status_ = mock_wifi_status;
}
static constexpr unsigned int kNetworkChangeTimeoutMs = 1000;
SystemGeolocationSourceApple();
~SystemGeolocationSourceApple() override;
void RegisterPermissionUpdateCallback(
PermissionUpdateCallback callback) override;
void PermissionUpdated();
void PositionUpdated(const mojom::Geoposition& position);
void PositionError(const mojom::GeopositionError& error);
void AddPositionUpdateObserver(PositionObserver* observer) override;
void RemovePositionUpdateObserver(PositionObserver* observer) override;
void StartWatchingPosition(bool high_accuracy) override;
void StopWatchingPosition() override;
void RequestPermission() override;
void OpenSystemPermissionSetting() override;
void StartWatchingPositionInternal(bool high_accuracy);
void StopWatchingPositionInternal();
void OnNetworkChanged(
net::NetworkChangeNotifier::ConnectionType type) override;
bool WasWifiEnabled() { return was_wifi_enabled_; }
void StartNetworkChangedTimer();
void OnNetworkChangedTimeout();
void SetLocationManagerForTesting(CLLocationManager* manager) {
location_manager_ = manager;
}
LocationManagerDelegate* GetDelegateForTesting() { return delegate_; }
#if BUILDFLAG(IS_IOS_TVOS)
void OnRequestLocationThrottleTimerFiring();
#endif
private:
friend class SystemGeolocationSourceAppleTest;
enum class CoreLocationSessionResult {
kSuccess = 0,
kCoreLocationError = 1,
kWifiDisabled = 2,
};
static std::optional<bool> mock_wifi_status_;
LocationSystemPermissionStatus GetSystemPermission() const;
LocationManagerDelegate* __strong delegate_;
CLLocationManager* __strong location_manager_;
PermissionUpdateCallback permission_update_callback_;
scoped_refptr<PositionObserverList> position_observers_;
base::RetainingOneShotTimer network_changed_timer_;
const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
bool was_wifi_enabled_ = false;
bool position_received_ = false;
std::optional<CoreLocationSessionResult> session_result_;
base::TimeTicks watch_start_time_;
#if BUILDFLAG(IS_IOS_TVOS)
base::OneShotTimer request_throttle_timer_;
#endif
base::WeakPtrFactory<SystemGeolocationSourceApple> weak_ptr_factory_{this};
};
}
#endif