author | Michael Harrison <mjh563@yahoo.co.uk> |
Tue, 15 Oct 2013 14:03:34 -0400 | |
changeset 165670 | 403bbc5e127fe42d7dbd1bfdf8a897df66862480 |
parent 165669 | b66f5da7a5e1f83f411acd8983a6642cbfa29c4f |
child 165671 | cf6610d2b9e7406b929471ef0dd0cc0bb89f4c84 |
push id | 428 |
push user | bbajaj@mozilla.com |
push date | Tue, 28 Jan 2014 00:16:25 +0000 |
treeherder | mozilla-release@cd72a7ff3a75 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jdm |
bugs | 914888 |
milestone | 27.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/src/geolocation/nsGeolocation.cpp +++ b/dom/src/geolocation/nsGeolocation.cpp @@ -72,17 +72,17 @@ class nsGeolocationRequest const GeoPositionCallback& aCallback, const GeoPositionErrorCallback& aErrorCallback, PositionOptions* aOptions, bool aWatchPositionRequest = false, int32_t aWatchId = 0); void Shutdown(); void SendLocation(nsIDOMGeoPosition* location); - bool WantsHighAccuracy() {return mOptions && mOptions->mEnableHighAccuracy;} + bool WantsHighAccuracy() {return !mShutdown && mOptions && mOptions->mEnableHighAccuracy;} void SetTimeoutTimer(); nsIPrincipal* GetPrincipal(); ~nsGeolocationRequest(); virtual bool Recv__delete__(const bool& allow) MOZ_OVERRIDE; virtual void IPDLRelease() MOZ_OVERRIDE { Release(); } @@ -457,17 +457,17 @@ nsGeolocationRequest::Allow() // if the user has specified a maximumAge, return a cached value. uint32_t maximumAge = 0; if (mOptions) { if (mOptions->mMaximumAge > 0) { maximumAge = mOptions->mMaximumAge; } } - gs->SetHigherAccuracy(mOptions && mOptions->mEnableHighAccuracy); + gs->UpdateAccuracy(WantsHighAccuracy()); bool canUseCache = lastPosition && maximumAge > 0 && (PRTime(PR_Now() / PR_USEC_PER_MSEC) - maximumAge <= PRTime(cachedPositionTime)); if (canUseCache) { // okay, we can return a cached position // getCurrentPosition requests serviced by the cache @@ -597,22 +597,22 @@ nsGeolocationRequest::Shutdown() MOZ_ASSERT(!mShutdown, "request shutdown twice"); mShutdown = true; if (mTimeoutTimer) { mTimeoutTimer->Cancel(); mTimeoutTimer = nullptr; } - // This should happen last, to ensure that this request isn't taken into consideration - // when deciding whether existing requests still require high accuracy. + // If there are no other high accuracy requests, the geolocation service will + // notify the provider to switch to the default accuracy. if (mOptions && mOptions->mEnableHighAccuracy) { nsRefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService(); if (gs) { - gs->SetHigherAccuracy(false); + gs->UpdateAccuracy(); } } } bool nsGeolocationRequest::Recv__delete__(const bool& allow) { if (allow) { (void) Allow(); @@ -915,19 +915,19 @@ nsGeolocationService::HighAccuracyReques if (mGeolocators[i]->HighAccuracyRequested()) { return true; } } return false; } void -nsGeolocationService::SetHigherAccuracy(bool aEnable) +nsGeolocationService::UpdateAccuracy(bool aForceHigh) { - bool highRequired = aEnable || HighAccuracyRequested(); + bool highRequired = aForceHigh || HighAccuracyRequested(); if (XRE_GetProcessType() == GeckoProcessType_Content) { ContentChild* cpc = ContentChild::GetSingleton(); cpc->SendSetGeolocationHigherAccuracy(highRequired); return; } if (!mHigherAccuracy && highRequired) { @@ -1075,16 +1075,17 @@ void Geolocation::Shutdown() { // Release all callbacks mPendingCallbacks.Clear(); mWatchingCallbacks.Clear(); if (mService) { mService->RemoveLocator(this); + mService->UpdateAccuracy(); } mService = nullptr; mPrincipal = nullptr; } nsIDOMWindow* Geolocation::GetParentObject() const {
--- a/dom/src/geolocation/nsGeolocation.h +++ b/dom/src/geolocation/nsGeolocation.h @@ -80,18 +80,18 @@ public: nsresult StartDevice(nsIPrincipal* aPrincipal); // Stop the started geolocation device (gps, nmea, etc.) void StopDevice(); // create, or reinitalize the callback timer void SetDisconnectTimer(); - // request higher accuracy, if possible - void SetHigherAccuracy(bool aEnable); + // Update the accuracy and notify the provider if changed + void UpdateAccuracy(bool aForceHigh = false); bool HighAccuracyRequested(); private: ~nsGeolocationService(); // Disconnect timer. When this timer expires, it clears all pending callbacks // and closes down the provider, unless we are watching a point, and in that
--- a/dom/system/NetworkGeolocationProvider.js +++ b/dom/system/NetworkGeolocationProvider.js @@ -68,16 +68,19 @@ function WifiGeoPositionProvider() { try { gUseScanning = Services.prefs.getBoolPref("geo.wifi.scan"); } catch (e) {} this.wifiService = null; this.timer = null; this.hasSeenWiFi = false; this.started = false; + // this is only used when logging is enabled, to debug interactions with the + // geolocation service + this.highAccuracy = false; } WifiGeoPositionProvider.prototype = { classID: Components.ID("{77DA64D3-7458-4920-9491-86CC9914F904}"), QueryInterface: XPCOMUtils.generateQI([Ci.nsIGeolocationProvider, Ci.nsIWifiListener, Ci.nsITimerCallback]), startup: function() { @@ -127,20 +130,22 @@ WifiGeoPositionProvider.prototype = { this.timer.cancel(); this.timer = null; } this.started = false; }, setHighAccuracy: function(enable) { + this.highAccuracy = enable; + LOG("setting highAccuracy to " + (this.highAccuracy?"TRUE":"FALSE")); }, onChange: function(accessPoints) { - LOG("onChange called"); + LOG("onChange called, highAccuracy = " + (this.highAccuracy?"TRUE":"FALSE")); this.hasSeenWiFi = true; let url = Services.urlFormatter.formatURLPref("geo.wifi.uri"); function isPublic(ap) { let mask = "_nomap" let result = ap.ssid.indexOf(mask, ap.ssid.length - mask.length) == -1; if (result != -1) {
new file mode 100644 --- /dev/null +++ b/dom/tests/unit/test_geolocation_reset_accuracy.js @@ -0,0 +1,104 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; + +const providerCID = Components.ID("{14aa4b81-e266-45cb-88f8-89595dece114}"); +const providerContract = "@mozilla.org/geolocation/provider;1"; + +const categoryName = "geolocation-provider"; + +var provider = { + QueryInterface: function eventsink_qi(iid) { + if (iid.equals(Components.interfaces.nsISupports) || + iid.equals(Components.interfaces.nsIFactory) || + iid.equals(Components.interfaces.nsIGeolocationProvider)) + return this; + throw Components.results.NS_ERROR_NO_INTERFACE; + }, + createInstance: function eventsink_ci(outer, iid) { + if (outer) + throw Components.results.NS_ERROR_NO_AGGREGATION; + return this.QueryInterface(iid); + }, + lockFactory: function eventsink_lockf(lock) { + throw Components.results.NS_ERROR_NOT_IMPLEMENTED; + }, + startup: function() { + }, + watch: function() { + }, + shutdown: function() { + }, + setHighAccuracy: function(enable) { + this._isHigh = enable; + if (enable) { + this._seenHigh = true; + } + }, + _isHigh: false, + _seenHigh: false +}; + +let runningInParent = true; +try { + runningInParent = Components.classes["@mozilla.org/xre/runtime;1"]. + getService(Components.interfaces.nsIXULRuntime).processType + == Components.interfaces.nsIXULRuntime.PROCESS_TYPE_DEFAULT; +} +catch (e) { } + +function successCallback() +{ + do_check_true(false); + do_test_finished(); +} + +function errorCallback() +{ + do_check_true(false); + do_test_finished(); +} + +function run_test() +{ + if (runningInParent) { + // XPCShell does not get a profile by default. The geolocation service + // depends on the settings service which uses IndexedDB and IndexedDB + // needs a place where it can store databases. + do_get_profile(); + + Components.manager.nsIComponentRegistrar.registerFactory(providerCID, + "Unit test geo provider", providerContract, provider); + var catMan = Components.classes["@mozilla.org/categorymanager;1"] + .getService(Components.interfaces.nsICategoryManager); + catMan.nsICategoryManager.addCategoryEntry(categoryName, "unit test", + providerContract, false, true); + + var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); + prefs.setBoolPref("geo.testing.ignore_ipc_principal", true); + prefs.setBoolPref("geo.wifi.scan", false); + } + + let geolocation = Cc["@mozilla.org/geolocation;1"].createInstance(Ci.nsISupports); + + do_test_pending(); + + let watchID1 = geolocation.watchPosition(successCallback, errorCallback); + let watchID2 = geolocation.watchPosition(successCallback, errorCallback, + {enableHighAccuracy: true}); + + do_timeout(1000, function() { + geolocation.clearWatch(watchID2); + do_timeout(1000, check_results); + }); +} + +function check_results() +{ + if (runningInParent) { + // check the provider was set to high accuracy during the test + do_check_true(provider._seenHigh); + // check the provider is not currently set to high accuracy + do_check_false(provider._isHigh); + } + do_test_finished(); +}
new file mode 100644 --- /dev/null +++ b/dom/tests/unit/test_geolocation_reset_accuracy_wrap.js @@ -0,0 +1,70 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; + +const providerCID = Components.ID("{14aa4b81-e266-45cb-88f8-89595dece114}"); +const providerContract = "@mozilla.org/geolocation/provider;1"; + +const categoryName = "geolocation-provider"; + +var provider = { + QueryInterface: function eventsink_qi(iid) { + if (iid.equals(Components.interfaces.nsISupports) || + iid.equals(Components.interfaces.nsIFactory) || + iid.equals(Components.interfaces.nsIGeolocationProvider)) + return this; + throw Components.results.NS_ERROR_NO_INTERFACE; + }, + createInstance: function eventsink_ci(outer, iid) { + if (outer) + throw Components.results.NS_ERROR_NO_AGGREGATION; + return this.QueryInterface(iid); + }, + lockFactory: function eventsink_lockf(lock) { + throw Components.results.NS_ERROR_NOT_IMPLEMENTED; + }, + startup: function() { + }, + watch: function() { + }, + shutdown: function() { + }, + setHighAccuracy: function(enable) { + this._isHigh = enable; + if (enable) { + this._seenHigh = true; + } + }, + _isHigh: false, + _seenHigh: false +}; + +function run_test() +{ + // XPCShell does not get a profile by default. The geolocation service + // depends on the settings service which uses IndexedDB and IndexedDB + // needs a place where it can store databases. + do_get_profile(); + + Components.manager.nsIComponentRegistrar.registerFactory(providerCID, + "Unit test geo provider", providerContract, provider); + var catMan = Components.classes["@mozilla.org/categorymanager;1"] + .getService(Components.interfaces.nsICategoryManager); + catMan.nsICategoryManager.addCategoryEntry(categoryName, "unit test", + providerContract, false, true); + + var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); + prefs.setBoolPref("geo.testing.ignore_ipc_principal", true); + prefs.setBoolPref("geo.wifi.scan", false); + + run_test_in_child("test_geolocation_reset_accuracy.js", check_results); +} + +function check_results() +{ + // check the provider was set to high accuracy during the test + do_check_true(provider._seenHigh); + // check the provider is not currently set to high accuracy + do_check_false(provider._isHigh); + + do_test_finished(); +}
--- a/dom/tests/unit/xpcshell.ini +++ b/dom/tests/unit/xpcshell.ini @@ -7,8 +7,13 @@ tail = [test_geolocation_provider.js] # Bug 684962: test hangs consistently on Android skip-if = os == "android" [test_geolocation_timeout.js] # Bug 919946: test hangs consistently on Android skip-if = os == "android" [test_geolocation_timeout_wrap.js] skip-if = os == "mac" || os == "android" +[test_geolocation_reset_accuracy.js] +# Bug 919946: test hangs consistently on Android +skip-if = os == "android" +[test_geolocation_reset_accuracy_wrap.js] +skip-if = os == "mac" || os == "android"