Created
October 7, 2013 04:21
-
-
Save jdm/6862469 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# HG changeset patch | |
# Parent 9366ee0396451492b3097fbb499b20fc5c63b82b | |
# User Josh Matthews <josh@joshmatthews.net> | |
diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp | |
--- a/dom/ipc/ContentParent.cpp | |
+++ b/dom/ipc/ContentParent.cpp | |
@@ -2724,16 +2724,17 @@ ContentParent::RecvAddGeolocationListene | |
} | |
} | |
#endif | |
// To ensure no geolocation updates are skipped, we always force the | |
// creation of a new listener. | |
RecvRemoveGeolocationListener(); | |
mGeolocationWatchID = AddGeolocationListener(this, aHighAccuracy); | |
+ mGeoUseHighAccuracy = aHighAccuracy; | |
return true; | |
} | |
bool | |
ContentParent::RecvRemoveGeolocationListener() | |
{ | |
if (mGeolocationWatchID != -1) { | |
nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1"); | |
@@ -2746,19 +2747,20 @@ ContentParent::RecvRemoveGeolocationList | |
return true; | |
} | |
bool | |
ContentParent::RecvSetGeolocationHigherAccuracy(const bool& aEnable) | |
{ | |
// This should never be called without a listener already present, | |
// so this check allows us to forgo securing privileges. | |
- if (mGeolocationWatchID != -1) { | |
+ if (mGeolocationWatchID != -1 && aEnable != mGeoUseHighAccuracy) { | |
RecvRemoveGeolocationListener(); | |
mGeolocationWatchID = AddGeolocationListener(this, aEnable); | |
+ mGeoUseHighAccuracy = aEnable; | |
} | |
return true; | |
} | |
NS_IMETHODIMP | |
ContentParent::HandleEvent(nsIDOMGeoPosition* postion) | |
{ | |
unused << SendGeolocationUpdate(GeoPosition(postion)); | |
diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h | |
--- a/dom/ipc/ContentParent.h | |
+++ b/dom/ipc/ContentParent.h | |
@@ -448,16 +448,17 @@ private: | |
// release these objects in ShutDownProcess. See the comment there for more | |
// details. | |
GeckoChildProcessHost* mSubprocess; | |
base::ChildPrivileges mOSPrivileges; | |
uint64_t mChildID; | |
int32_t mGeolocationWatchID; | |
+ bool mGeoUseHighAccuracy; | |
// This is a reporter holding the reports from the child's last | |
// "child-memory-reporter-update" notification. To update this, one can | |
// broadcast the topic "child-memory-reporter-request" using the | |
// nsIObserverService. | |
// | |
// Note that this assumes there is at most one child process at a time! | |
nsCOMPtr<nsIMemoryReporter> mChildReporter; | |
diff --git a/dom/src/geolocation/nsGeolocation.cpp b/dom/src/geolocation/nsGeolocation.cpp | |
--- a/dom/src/geolocation/nsGeolocation.cpp | |
+++ b/dom/src/geolocation/nsGeolocation.cpp | |
@@ -72,16 +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 !mShutdown && mOptions && mOptions->enableHighAccuracy;} | |
bool WantsHighAccuracy() {return mOptions && mOptions->mEnableHighAccuracy;} | |
void SetTimeoutTimer(); | |
nsIPrincipal* GetPrincipal(); | |
~nsGeolocationRequest(); | |
virtual bool Recv__delete__(const bool& allow) MOZ_OVERRIDE; | |
virtual void IPDLRelease() MOZ_OVERRIDE { Release(); } | |
@@ -434,17 +435,17 @@ nsGeolocationRequest::Cancel() | |
return NS_OK; | |
} | |
NS_IMETHODIMP | |
nsGeolocationRequest::Allow() | |
{ | |
// Kick off the geo device, if it isn't already running | |
nsRefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService(); | |
- nsresult rv = gs->StartDevice(GetPrincipal()); | |
+ nsresult rv = gs->StartDevice(GetPrincipal(), WantsHighAccuracy()); | |
if (NS_FAILED(rv)) { | |
// Location provider error | |
NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE); | |
return NS_OK; | |
} | |
nsCOMPtr<nsIDOMGeoPosition> lastPosition = gs->GetCachedPosition(); | |
@@ -461,17 +462,17 @@ nsGeolocationRequest::Allow() | |
// b) the cached position time is some reasonable value to return to the user (<30s) | |
uint32_t maximumAge = 30 * PR_MSEC_PER_SEC; | |
if (mOptions) { | |
if (mOptions->mMaximumAge >= 0) { | |
maximumAge = mOptions->mMaximumAge; | |
} | |
} | |
- gs->SetHigherAccuracy(mOptions && mOptions->mEnableHighAccuracy); | |
+ gs->SetHigherAccuracy(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 | |
@@ -847,31 +848,31 @@ nsGeolocationService::SetCachedPosition( | |
nsIDOMGeoPosition* | |
nsGeolocationService::GetCachedPosition() | |
{ | |
return mLastPosition; | |
} | |
nsresult | |
-nsGeolocationService::StartDevice(nsIPrincipal *aPrincipal) | |
+nsGeolocationService::StartDevice(nsIPrincipal *aPrincipal, bool aEnableHighAccuracy) | |
{ | |
if (!sGeoEnabled || sGeoInitPending) { | |
return NS_ERROR_NOT_AVAILABLE; | |
} | |
// we do not want to keep the geolocation devices online | |
// indefinitely. Close them down after a reasonable period of | |
// inactivivity | |
SetDisconnectTimer(); | |
if (XRE_GetProcessType() == GeckoProcessType_Content) { | |
ContentChild* cpc = ContentChild::GetSingleton(); | |
cpc->SendAddGeolocationListener(IPC::Principal(aPrincipal), | |
- HighAccuracyRequested()); | |
+ aEnableHighAccuracy || HighAccuracyRequested()); | |
return NS_OK; | |
} | |
// Start them up! | |
nsCOMPtr<nsIObserverService> obs = services::GetObserverService(); | |
if (!obs) { | |
return NS_ERROR_FAILURE; | |
} | |
diff --git a/dom/src/geolocation/nsGeolocation.h b/dom/src/geolocation/nsGeolocation.h | |
--- a/dom/src/geolocation/nsGeolocation.h | |
+++ b/dom/src/geolocation/nsGeolocation.h | |
@@ -72,17 +72,17 @@ public: | |
// Management of the Geolocation objects | |
void AddLocator(mozilla::dom::Geolocation* locator); | |
void RemoveLocator(mozilla::dom::Geolocation* locator); | |
void SetCachedPosition(nsIDOMGeoPosition* aPosition); | |
nsIDOMGeoPosition* GetCachedPosition(); | |
// Find and startup a geolocation device (gps, nmea, etc.) | |
- nsresult StartDevice(nsIPrincipal* aPrincipal); | |
+ nsresult StartDevice(nsIPrincipal* aPrincipal, bool aEnableHighAccuracy); | |
// Stop the started geolocation device (gps, nmea, etc.) | |
void StopDevice(); | |
// create, or reinitalize the callback timer | |
void SetDisconnectTimer(); | |
// request higher accuracy, if possible | |
diff --git a/dom/tests/unit/test_high_accuracy_timeout.js b/dom/tests/unit/test_high_accuracy_timeout.js | |
new file mode 100644 | |
--- /dev/null | |
+++ b/dom/tests/unit/test_high_accuracy_timeout.js | |
@@ -0,0 +1,93 @@ | |
+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() { | |
+ do_print("startup"); | |
+ }, | |
+ watch: function(callback, isPrivate) { | |
+ do_print("watch"); | |
+ /*do_execute_soon(function() { | |
+ callback.update({coords: {latitude: 42, longitude: 42}, timestamp: 0}); | |
+ });*/ | |
+ }, | |
+ shutdown: function() { | |
+ do_print("shutdown"); | |
+ do_execute_soon(do_test_finished); | |
+ }, | |
+ setHighAccuracy: function(enable) { | |
+ do_print("high: " + enable); | |
+ if (enable) { | |
+ this._seenHigh = true; | |
+ } else { | |
+ this._seenNotHigh = true; | |
+ } | |
+ }, | |
+ _seenHigh: false, | |
+ _seenNotHigh: 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) { } | |
+ | |
+var geolocation; | |
+function run_test() | |
+{ | |
+ do_test_pending(); | |
+ | |
+ if (runningInParent) { | |
+ 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); | |
+ } | |
+ | |
+ do_print("hi"); | |
+ geolocation = Cc["@mozilla.org/geolocation;1"].createInstance(Ci.nsISupports); | |
+ geolocation.getCurrentPosition(function() { do_check_true(false); }, | |
+ function() { | |
+ do_print("timed out"); | |
+ if (!runningInParent) { | |
+ do_test_finished(); | |
+ } | |
+ //do_test_finished(); | |
+ /*geolocation.getCurrentPosition(function() { | |
+ if (runningInParent) { | |
+ do_check_true(provider._seenNotHigh); | |
+ do_check_true(provider._seenHigh); | |
+ } | |
+ do_test_finished(); | |
+ }, null, {enableHighAccuracy: false, maxAge: 0});*/ | |
+ }, {enableHighAccuracy: true, timeout: 1}); | |
+} | |
\ No newline at end of file | |
diff --git a/dom/tests/unit/test_high_accuracy_timeout_wrap.js b/dom/tests/unit/test_high_accuracy_timeout_wrap.js | |
new file mode 100644 | |
--- /dev/null | |
+++ b/dom/tests/unit/test_high_accuracy_timeout_wrap.js | |
@@ -0,0 +1,67 @@ | |
+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() { | |
+ do_print("startup"); | |
+ }, | |
+ watch: function(callback, isPrivate) { | |
+ do_print("watch"); | |
+ /*do_execute_soon(function() { | |
+ callback.update({coords: {latitude: 42, longitude: 42}, timestamp: 0}); | |
+ });*/ | |
+ }, | |
+ shutdown: function() { | |
+ do_print("shutdown"); | |
+ do_execute_soon(do_test_finished); | |
+ }, | |
+ setHighAccuracy: function(enable) { | |
+ do_print("high: " + enable); | |
+ if (enable) { | |
+ this._seenHigh = true; | |
+ } else { | |
+ this._seenNotHigh = true; | |
+ } | |
+ }, | |
+ _seenHigh: false, | |
+ _seenNotHigh: false | |
+}; | |
+ | |
+ | |
+function run_test() | |
+{ | |
+ 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_high_accuracy_timeout.js", function() { | |
+ //do_check_true(provider._seenNotHigh); | |
+ //do_check_true(provider._seenHigh); | |
+ //do_test_finished(); | |
+ }); | |
+} | |
diff --git a/dom/tests/unit/xpcshell.ini b/dom/tests/unit/xpcshell.ini | |
--- a/dom/tests/unit/xpcshell.ini | |
+++ b/dom/tests/unit/xpcshell.ini | |
@@ -5,8 +5,10 @@ tail = | |
[test_bug319968.js] | |
[test_bug465752.js] | |
[test_geolocation_provider.js] | |
# Bug 684962: test hangs consistently on Android | |
skip-if = os == "android" | |
[test_geolocation_timeout.js] | |
[test_geolocation_timeout_wrap.js] | |
skip-if = os == "mac" || os == "android" | |
+[test_high_accuracy_timeout.js] | |
+[test_high_accuracy_timeout_wrap.js] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment