Bug 1803234 - Remove gpsd support. r=emilio

Firefox's gpsd support is unmaintained and disabled by default.

Differential Revision: https://phabricator.services.mozilla.com/D218418
This commit is contained in:
Chris Peterson 2024-08-05 16:04:08 +00:00
parent 327f808e92
commit e4c83ed7e3
10 changed files with 1 additions and 555 deletions

View File

@ -45,9 +45,6 @@ DEFINES["APP_VERSION"] = CONFIG["MOZ_APP_VERSION"]
for cdm in CONFIG["MOZ_EME_MODULES"]:
DEFINES["MOZ_%s_EME" % cdm.upper()] = True
if CONFIG["MOZ_GPSD"]:
DEFINES["MOZ_GPSD"] = True
if CONFIG["MOZ_UPDATE_AGENT"]:
DEFINES["MOZ_UPDATE_AGENT"] = True

View File

@ -316,7 +316,6 @@ system_headers = [
"gmodule.h",
"gnome.h",
"gnu/libc-version.h",
"gps.h",
"grp.h",
"gssapi_generic.h",
"gssapi/gssapi_generic.h",

View File

@ -40,10 +40,6 @@ class nsIPrincipal;
# include "AndroidLocationProvider.h"
#endif
#ifdef MOZ_GPSD
# include "GpsdLocationProvider.h"
#endif
#ifdef MOZ_ENABLE_DBUS
# include "mozilla/WidgetUtilsGtk.h"
# include "GeoclueLocationProvider.h"
@ -543,7 +539,7 @@ nsresult nsGeolocationService::Init() {
.EnumGet(glean::geolocation::LinuxProviderLabel::ePortal)
.Set(true);
}
// Geoclue includes GPS data so it has higher priority than raw GPSD
if (!mProvider && StaticPrefs::geo_provider_use_geoclue()) {
nsCOMPtr<nsIGeolocationProvider> gcProvider = new GeoclueLocationProvider();
MOZ_LOG(gGeolocationLog, LogLevel::Debug,
@ -559,16 +555,6 @@ nsresult nsGeolocationService::Init() {
.Set(true);
}
}
# ifdef MOZ_GPSD
if (!mProvider && Preferences::GetBool("geo.provider.use_gpsd", false)) {
mProvider = new GpsdLocationProvider();
MOZ_LOG(gGeolocationLog, LogLevel::Debug,
("Selected GpsdLocationProvider"));
glean::geolocation::linux_provider
.EnumGet(glean::geolocation::LinuxProviderLabel::eGpsd)
.Set(true);
}
# endif
# endif
#endif

View File

@ -67,7 +67,6 @@ geolocation:
- none
- portal
- geoclue
- gpsd
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1905928
data_reviews:

View File

@ -50,11 +50,6 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
"/dom/system/windows/location",
]
elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
if CONFIG["MOZ_GPSD"]:
LOCAL_INCLUDES += [
"/dom/system/linux",
]
DEFINES["MOZ_GPSD"] = True
if CONFIG["MOZ_ENABLE_DBUS"]:
LOCAL_INCLUDES += ["/dom/system/linux"]
CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"]

View File

@ -1,446 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GpsdLocationProvider.h"
#include <errno.h>
#include <gps.h>
#include "MLSFallback.h"
#include "mozilla/Atomics.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/LazyIdleThread.h"
#include "mozilla/dom/GeolocationPositionErrorBinding.h"
#include "GeolocationPosition.h"
#include "nsProxyRelease.h"
#include "nsThreadUtils.h"
#include "prtime.h"
namespace mozilla {
namespace dom {
//
// MLSGeolocationUpdate
//
/**
* |MLSGeolocationUpdate| provides a fallback if gpsd is not supported.
*/
class GpsdLocationProvider::MLSGeolocationUpdate final
: public nsIGeolocationUpdate {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGEOLOCATIONUPDATE
explicit MLSGeolocationUpdate(nsIGeolocationUpdate* aCallback);
protected:
~MLSGeolocationUpdate() = default;
private:
nsCOMPtr<nsIGeolocationUpdate> mCallback;
};
GpsdLocationProvider::MLSGeolocationUpdate::MLSGeolocationUpdate(
nsIGeolocationUpdate* aCallback)
: mCallback(aCallback) {
MOZ_ASSERT(mCallback);
}
// nsISupports
//
NS_IMPL_ISUPPORTS(GpsdLocationProvider::MLSGeolocationUpdate,
nsIGeolocationUpdate);
// nsIGeolocationUpdate
//
NS_IMETHODIMP
GpsdLocationProvider::MLSGeolocationUpdate::Update(
nsIDOMGeoPosition* aPosition) {
nsCOMPtr<nsIDOMGeoPositionCoords> coords;
aPosition->GetCoords(getter_AddRefs(coords));
if (!coords) {
return NS_ERROR_FAILURE;
}
return mCallback->Update(aPosition);
}
NS_IMETHODIMP
GpsdLocationProvider::MLSGeolocationUpdate::NotifyError(uint16_t aError) {
return mCallback->NotifyError(aError);
}
//
// UpdateRunnable
//
class GpsdLocationProvider::UpdateRunnable final : public Runnable {
public:
UpdateRunnable(
const nsMainThreadPtrHandle<GpsdLocationProvider>& aLocationProvider,
nsIDOMGeoPosition* aPosition)
: Runnable("GpsdU"),
mLocationProvider(aLocationProvider),
mPosition(aPosition) {
MOZ_ASSERT(mLocationProvider);
MOZ_ASSERT(mPosition);
}
// nsIRunnable
//
NS_IMETHOD Run() override {
mLocationProvider->Update(mPosition);
return NS_OK;
}
private:
nsMainThreadPtrHandle<GpsdLocationProvider> mLocationProvider;
RefPtr<nsIDOMGeoPosition> mPosition;
};
//
// NotifyErrorRunnable
//
class GpsdLocationProvider::NotifyErrorRunnable final : public Runnable {
public:
NotifyErrorRunnable(
const nsMainThreadPtrHandle<GpsdLocationProvider>& aLocationProvider,
int aError)
: Runnable("GpsdNE"),
mLocationProvider(aLocationProvider),
mError(aError) {
MOZ_ASSERT(mLocationProvider);
}
// nsIRunnable
//
NS_IMETHOD Run() override {
mLocationProvider->NotifyError(mError);
return NS_OK;
}
private:
nsMainThreadPtrHandle<GpsdLocationProvider> mLocationProvider;
int mError;
};
//
// PollRunnable
//
/**
* |PollRunnable| does the main work of processing GPS data received
* from gpsd. libgps blocks while polling, so this runnable has to be
* executed on it's own thread. To cancel the poll runnable, invoke
* |StopRunning| and |PollRunnable| will stop within a reasonable time
* frame.
*/
class GpsdLocationProvider::PollRunnable final : public Runnable {
public:
PollRunnable(
const nsMainThreadPtrHandle<GpsdLocationProvider>& aLocationProvider)
: Runnable("GpsdP"),
mLocationProvider(aLocationProvider),
mRunning(true) {
MOZ_ASSERT(mLocationProvider);
}
static bool IsSupported() {
return GPSD_API_MAJOR_VERSION >= 5 && GPSD_API_MAJOR_VERSION <= 12;
}
bool IsRunning() const { return mRunning; }
void StopRunning() { mRunning = false; }
// nsIRunnable
//
NS_IMETHOD Run() override {
int err;
switch (GPSD_API_MAJOR_VERSION) {
case 5 ... 12:
err = PollLoop5();
break;
default:
err = GeolocationPositionError_Binding::POSITION_UNAVAILABLE;
break;
}
if (err) {
NS_DispatchToMainThread(
MakeAndAddRef<NotifyErrorRunnable>(mLocationProvider, err));
}
mLocationProvider = nullptr;
return NS_OK;
}
protected:
int PollLoop5() {
#if GPSD_API_MAJOR_VERSION >= 5 && GPSD_API_MAJOR_VERSION <= 12
static const int GPSD_WAIT_TIMEOUT_US =
1000000; /* us to wait for GPS data */
struct gps_data_t gpsData;
auto res = gps_open(nullptr, nullptr, &gpsData);
if (res < 0) {
return ErrnoToError(errno);
}
gps_stream(&gpsData, WATCH_ENABLE | WATCH_JSON, NULL);
int err = 0;
// nsGeoPositionCoords will convert NaNs to null for optional properties of
// the JavaScript Coordinates object.
double lat = 0;
double lon = 0;
double alt = UnspecifiedNaN<double>();
double hError = 0;
double vError = UnspecifiedNaN<double>();
double heading = UnspecifiedNaN<double>();
double speed = UnspecifiedNaN<double>();
while (IsRunning()) {
errno = 0;
auto hasGpsData = gps_waiting(&gpsData, GPSD_WAIT_TIMEOUT_US);
if (errno) {
err = ErrnoToError(errno);
break;
}
if (!hasGpsData) {
continue; /* woke up from timeout */
}
# if GPSD_API_MAJOR_VERSION >= 7
res = gps_read(&gpsData, nullptr, 0);
# else
res = gps_read(&gpsData);
# endif
if (res < 0) {
err = ErrnoToError(errno);
break;
} else if (!res) {
continue; /* no data available */
}
# if GPSD_API_MAJOR_VERSION < 10
if (gpsData.status == STATUS_NO_FIX) {
continue;
}
# endif
switch (gpsData.fix.mode) {
case MODE_3D:
double galt;
# if GPSD_API_MAJOR_VERSION >= 9
galt = gpsData.fix.altMSL;
# else
galt = gpsData.fix.altitude;
# endif
if (!std::isnan(galt)) {
alt = galt;
}
[[fallthrough]];
case MODE_2D:
if (!std::isnan(gpsData.fix.latitude)) {
lat = gpsData.fix.latitude;
}
if (!std::isnan(gpsData.fix.longitude)) {
lon = gpsData.fix.longitude;
}
if (!std::isnan(gpsData.fix.epx) && !std::isnan(gpsData.fix.epy)) {
hError = std::max(gpsData.fix.epx, gpsData.fix.epy);
} else if (!std::isnan(gpsData.fix.epx)) {
hError = gpsData.fix.epx;
} else if (!std::isnan(gpsData.fix.epy)) {
hError = gpsData.fix.epy;
}
if (!std::isnan(gpsData.fix.epv)) {
vError = gpsData.fix.epv;
}
if (!std::isnan(gpsData.fix.track)) {
heading = gpsData.fix.track;
}
if (!std::isnan(gpsData.fix.speed)) {
speed = gpsData.fix.speed;
}
break;
default:
continue; // There's no useful data in this fix; continue.
}
NS_DispatchToMainThread(MakeAndAddRef<UpdateRunnable>(
mLocationProvider,
new nsGeoPosition(lat, lon, alt, hError, vError, heading, speed,
PR_Now() / PR_USEC_PER_MSEC)));
}
gps_stream(&gpsData, WATCH_DISABLE, NULL);
gps_close(&gpsData);
return err;
#else
return GeolocationPositionError_Binding::POSITION_UNAVAILABLE;
#endif // GPSD_MAJOR_API_VERSION
}
static int ErrnoToError(int aErrno) {
switch (aErrno) {
case EACCES:
[[fallthrough]];
case EPERM:
[[fallthrough]];
case EROFS:
return GeolocationPositionError_Binding::PERMISSION_DENIED;
case ETIME:
[[fallthrough]];
case ETIMEDOUT:
return GeolocationPositionError_Binding::TIMEOUT;
default:
return GeolocationPositionError_Binding::POSITION_UNAVAILABLE;
}
}
private:
nsMainThreadPtrHandle<GpsdLocationProvider> mLocationProvider;
Atomic<bool> mRunning;
};
//
// GpsdLocationProvider
//
const uint32_t GpsdLocationProvider::GPSD_POLL_THREAD_TIMEOUT_MS = 5000;
GpsdLocationProvider::GpsdLocationProvider() {}
GpsdLocationProvider::~GpsdLocationProvider() {}
void GpsdLocationProvider::Update(nsIDOMGeoPosition* aPosition) {
if (!mCallback || !mPollRunnable) {
return; // not initialized or already shut down
}
if (mMLSProvider) {
/* We got a location from gpsd, so let's cancel our MLS fallback. */
mMLSProvider->Shutdown(MLSFallback::ShutdownReason::ProviderResponded);
mMLSProvider = nullptr;
}
mCallback->Update(aPosition);
}
void GpsdLocationProvider::NotifyError(int aError) {
if (!mCallback) {
return; // not initialized or already shut down
}
if (!mMLSProvider) {
/* With gpsd failed, we restart MLS. It will be canceled once we
* get another location from gpsd.
*/
mMLSProvider = MakeAndAddRef<MLSFallback>();
mMLSProvider->Startup(new MLSGeolocationUpdate(mCallback));
}
mCallback->NotifyError(aError);
}
// nsISupports
//
NS_IMPL_ISUPPORTS(GpsdLocationProvider, nsIGeolocationProvider)
// nsIGeolocationProvider
//
NS_IMETHODIMP
GpsdLocationProvider::Startup() {
if (!PollRunnable::IsSupported()) {
return NS_OK; // We'll fall back to MLS.
}
if (mPollRunnable) {
return NS_OK; // already running
}
RefPtr<PollRunnable> pollRunnable =
MakeAndAddRef<PollRunnable>(nsMainThreadPtrHandle<GpsdLocationProvider>(
new nsMainThreadPtrHolder<GpsdLocationProvider>("GpsdLP", this)));
// Use existing poll thread...
RefPtr<LazyIdleThread> pollThread = mPollThread;
// ... or create a new one.
if (!pollThread) {
pollThread = MakeAndAddRef<LazyIdleThread>(GPSD_POLL_THREAD_TIMEOUT_MS,
"Gpsd poll thread",
LazyIdleThread::ManualShutdown);
}
auto rv = pollThread->Dispatch(pollRunnable, NS_DISPATCH_NORMAL);
if (NS_FAILED(rv)) {
return rv;
}
mPollRunnable = pollRunnable.forget();
mPollThread = pollThread.forget();
return NS_OK;
}
NS_IMETHODIMP
GpsdLocationProvider::Watch(nsIGeolocationUpdate* aCallback) {
mCallback = aCallback;
/* The MLS fallback will kick in after a few seconds if gpsd
* doesn't provide location information within time. Once we
* see the first message from gpsd, the fallback will be
* disabled in |Update|.
*/
mMLSProvider = MakeAndAddRef<MLSFallback>();
mMLSProvider->Startup(new MLSGeolocationUpdate(aCallback));
return NS_OK;
}
NS_IMETHODIMP
GpsdLocationProvider::Shutdown() {
if (mMLSProvider) {
mMLSProvider->Shutdown(MLSFallback::ShutdownReason::ProviderShutdown);
mMLSProvider = nullptr;
}
if (!mPollRunnable) {
return NS_OK; // not running
}
mPollRunnable->StopRunning();
mPollRunnable = nullptr;
return NS_OK;
}
NS_IMETHODIMP
GpsdLocationProvider::SetHighAccuracy(bool aHigh) { return NS_OK; }
} // namespace dom
} // namespace mozilla

View File

@ -1,51 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GpsdLocationProvider_h
#define GpsdLocationProvider_h
#include "nsCOMPtr.h"
#include "Geolocation.h"
#include "nsIGeolocationProvider.h"
class MLSFallback;
namespace mozilla {
class LazyIdleThread;
namespace dom {
class GpsdLocationProvider final : public nsIGeolocationProvider {
class MLSGeolocationUpdate;
class NotifyErrorRunnable;
class PollRunnable;
class UpdateRunnable;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGEOLOCATIONPROVIDER
GpsdLocationProvider();
private:
~GpsdLocationProvider();
void Update(nsIDOMGeoPosition* aPosition);
void NotifyError(int aError);
static const uint32_t GPSD_POLL_THREAD_TIMEOUT_MS;
nsCOMPtr<nsIGeolocationUpdate> mCallback;
RefPtr<LazyIdleThread> mPollThread;
RefPtr<PollRunnable> mPollRunnable;
RefPtr<MLSFallback> mMLSProvider;
};
} // namespace dom
} // namespace mozilla
#endif /* GpsLocationProvider_h */

View File

@ -4,16 +4,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
if CONFIG["MOZ_GPSD"]:
SOURCES += ["GpsdLocationProvider.cpp"]
CXXFLAGS += CONFIG["MOZ_GPSD_CFLAGS"]
OS_LIBS += CONFIG["MOZ_GPSD_LIBS"]
LOCAL_INCLUDES += ["/dom/geolocation"]
if CONFIG["MOZ_ENABLE_DBUS"]:
SOURCES += ["GeoclueLocationProvider.cpp"]
SOURCES += ["PortalLocationProvider.cpp"]

View File

@ -3236,10 +3236,6 @@ pref("geo.provider.network.timeout", 60000);
pref("geo.provider.ms-windows-location", true);
#endif
#if defined(MOZ_WIDGET_GTK) && defined(MOZ_GPSD)
pref("geo.provider.use_gpsd", true);
#endif
// Region
pref("browser.region.log", false);
pref("browser.region.network.url", "https://location.services.mozilla.com/v1/country?key=%MOZILLA_API_KEY%");

View File

@ -1177,25 +1177,6 @@ def telemetry_on_by_default(reporting, is_nightly):
set_define("MOZ_TELEMETRY_ON_BY_DEFAULT", True, when=telemetry_on_by_default)
# gpsd support
# ==============================================================
system_lib_option(
"--enable-gpsd",
env="MOZ_GPSD",
help="Enable gpsd support",
when=use_pkg_config,
)
@depends("--enable-gpsd", when=use_pkg_config)
def gpsd(value):
return bool(value)
system_gpsd = pkg_check_modules("MOZ_GPSD", "libgps >= 3.11", when=gpsd)
set_config("MOZ_GPSD", depends_if(system_gpsd)(lambda _: True))
# Miscellaneous programs
# ==============================================================