Bug 1962205 - Move locators insted of running two geolocation services at a time. r=saschanaz

Differential Revision: https://phabricator.services.mozilla.com/D246564
This commit is contained in:
Alexandra Borovova
2025-04-28 08:15:10 +00:00
parent 5a70acfb01
commit 5374867f8e
4 changed files with 101 additions and 19 deletions

View File

@@ -3255,6 +3255,11 @@ void BrowsingContext::SetGeolocationServiceOverride(
}
mGeolocationServiceOverride->Update(aGeolocationOverride.Value());
} else {
// Create an original service and move the locators.
RefPtr<nsGeolocationService> service =
nsGeolocationService::GetGeolocationService();
mGeolocationServiceOverride->MoveLocators(service);
mGeolocationServiceOverride = nullptr;
}
}

View File

@@ -1003,6 +1003,12 @@ void nsGeolocationService::RemoveLocator(Geolocation* aLocator) {
mGeolocators.RemoveElement(aLocator);
}
void nsGeolocationService::MoveLocators(nsGeolocationService* aService) {
for (uint32_t i = 0; i < mGeolocators.Length(); i++) {
aService->AddLocator(mGeolocators[i]);
}
}
////////////////////////////////////////////////////
// Geolocation
////////////////////////////////////////////////////
@@ -1074,23 +1080,12 @@ nsresult Geolocation::Init(nsPIDOMWindowInner* aContentDom) {
// If no aContentDom was passed into us, we are being used
// by chrome/c++ and have no mOwner, no mPrincipal, and no need
// to prompt.
RefPtr<nsGeolocationService> service =
nsGeolocationService::GetGeolocationService(mBrowsingContext);
if (service != nsGeolocationService::sService.get()) {
mService = nsGeolocationService::GetGeolocationService();
mServiceOverride = service;
} else {
mService = service;
}
mService = nsGeolocationService::GetGeolocationService(mBrowsingContext);
if (mService) {
mService->AddLocator(this);
}
if (mServiceOverride) {
mServiceOverride->AddLocator(this);
}
return NS_OK;
}
@@ -1104,12 +1099,7 @@ void Geolocation::Shutdown() {
mService->UpdateAccuracy();
}
if (mServiceOverride) {
mServiceOverride->RemoveLocator(this);
}
mService = nullptr;
mServiceOverride = nullptr;
mPrincipal = nullptr;
}

View File

@@ -70,8 +70,11 @@ class nsGeolocationService final : public nsIGeolocationUpdate,
nsresult Init();
// Management of the Geolocation objects
void AddLocator(mozilla::dom::Geolocation* locator);
void RemoveLocator(mozilla::dom::Geolocation* locator);
void AddLocator(mozilla::dom::Geolocation* aLocator);
void RemoveLocator(mozilla::dom::Geolocation* aLocator);
// Move locators from service override to the original service.
void MoveLocators(nsGeolocationService* aService);
void SetCachedPosition(nsIDOMGeoPosition* aPosition);
CachedPositionAndAccuracy GetCachedPosition();

View File

@@ -356,3 +356,87 @@ add_task(async function test_tab_reload() {
BrowserTestUtils.removeTab(tab);
});
add_task(async function test_amount_of_updates_for_watchPosition() {
await SpecialPowers.pushPrefEnv({
set: required_preferences,
});
let pageLoaded;
let browser;
const tab = await BrowserTestUtils.openNewForegroundTab(
gBrowser,
() => {
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, PAGE_URL);
browser = gBrowser.selectedBrowser;
pageLoaded = BrowserTestUtils.browserLoaded(browser, true);
},
false
);
await pageLoaded;
await SpecialPowers.spawn(browser, [], async () => {
await SpecialPowers.pushPermissions([
{
type: "geo",
allow: SpecialPowers.Services.perms.ALLOW_ACTION,
context: content.document,
},
]);
const browsingContext = content.browsingContext;
// Set the initial override before the watchPosition is started.
browsingContext.setGeolocationServiceOverride({
coords: {
latitude: 0,
longitude: 0,
accuracy: 0,
altitude: NaN,
altitudeAccuracy: NaN,
heading: NaN,
speed: NaN,
},
timestamp: Date.now(),
});
const watchID = content.window.navigator.geolocation.watchPosition(
result => {
const event = new content.window.CustomEvent("watchPosition", {
detail: result.coords.toJSON(),
});
content.document.dispatchEvent(event);
}
);
const events = [];
info("Override the geolocation");
content.document.addEventListener("watchPosition", e => {
content.window.console.log("test");
events.push(e.detail);
});
browsingContext.setGeolocationServiceOverride({
coords: {
latitude: 10,
longitude: 10,
accuracy: 5,
altitude: NaN,
altitudeAccuracy: NaN,
heading: NaN,
speed: NaN,
},
timestamp: Date.now(),
});
await ContentTaskUtils.waitForCondition(() => !!events.length);
is(events.length, 1, "Only one event should come after override is set");
content.window.navigator.geolocation.clearWatch(watchID);
});
BrowserTestUtils.removeTab(tab);
});