Bug 882485 - Add API keys support for Google Location Service API. r=gps, jdm, gavin. sr=brendan
authorDoug Turner <doug.turner@gmail.com>
Wed, 12 Jun 2013 19:20:07 -0700
changeset 147528 6c236b24064bbd67c167165cd5958c2b432df7a1
parent 147527 75948a6ea38dab47aafa7132ba17a099d95c09ec
child 147529 7c0453f3ed7083608db1189f4506be030c6055e7
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps, jdm, gavin, brendan
bugs882485
milestone24.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
Bug 882485 - Add API keys support for Google Location Service API. r=gps, jdm, gavin. sr=brendan
browser/app/profile/firefox.js
browser/base/content/sanitize.js
browser/metro/base/content/sanitize.js
configure.in
dom/src/geolocation/nsGeolocation.cpp
dom/src/geolocation/nsGeolocation.h
dom/system/NetworkGeolocationProvider.js
dom/system/android/AndroidLocationProvider.cpp
dom/system/gonk/GonkGPSGeolocationProvider.cpp
dom/system/unix/MaemoLocationProvider.cpp
dom/system/unix/QTMLocationProvider.cpp
mobile/android/modules/Sanitizer.jsm
toolkit/components/urlformatter/Makefile.in
toolkit/components/urlformatter/moz.build
toolkit/components/urlformatter/nsURLFormatter.js
toolkit/forgetaboutsite/ForgetAboutSite.jsm
xpcom/system/nsIGeolocationProvider.idl
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1268,8 +1268,11 @@ pref("plain_text.wrap_long_lines", true)
 #ifndef RELEASE_BUILD
 // Enable Web Audio for Firefox Desktop in Nightly and Aurora
 pref("media.webaudio.enabled", true);
 #endif
 
 // If this turns true, Moz*Gesture events are not called stopPropagation()
 // before content.
 pref("dom.debug.propagate_gesture_events_through_content", false);
+
+// The request URL of the GeoLocation backend.
+pref("geo.wifi.uri", "https://www.googleapis.com/geolocation/v1/geolocate?key=%GOOGLE_API_KEY%");
--- a/browser/base/content/sanitize.js
+++ b/browser/base/content/sanitize.js
@@ -172,25 +172,16 @@ Sanitizer.prototype = {
                   ph.clearSiteData(tags[i], null, FLAG_CLEAR_ALL, -1);
                 } catch (e) {
                   // Ignore errors from the plugin
                 }
               }
             }
           }
         }
-
-        // clear any network geolocation provider sessions
-        var psvc = Components.classes["@mozilla.org/preferences-service;1"]
-                             .getService(Components.interfaces.nsIPrefService);
-        try {
-            var branch = psvc.getBranch("geo.wifi.access_token.");
-            branch.deleteBranch("");
-        } catch (e) {}
-
       },
 
       get canClear()
       {
         return true;
       }
     },
 
--- a/browser/metro/base/content/sanitize.js
+++ b/browser/metro/base/content/sanitize.js
@@ -95,25 +95,16 @@ Sanitizer.prototype = {
       }
     },
     
     cookies: {
       clear: function ()
       {
         var cookieMgr = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager);
         cookieMgr.removeAll();
-
-        // clear any network geolocation provider sessions
-        try {
-          var branch = Services.prefs.getBranch("geo.wifi.access_token.");
-          branch.deleteBranch("");
-
-          branch = Services.prefs.getBranch("geo.request.remember.");
-          branch.deleteBranch("");
-        } catch (e) {dump(e);}
       },
       
       get canClear()
       {
         return true;
       }
     },
 
--- a/configure.in
+++ b/configure.in
@@ -4327,16 +4327,26 @@ MOZ_ARG_ENABLE_STRING([update-channel],
     MOZ_UPDATE_CHANNEL=`echo $enableval | tr A-Z a-z`)
 
 if test -z "$MOZ_UPDATE_CHANNEL"; then
     MOZ_UPDATE_CHANNEL=default
 fi
 AC_DEFINE_UNQUOTED(MOZ_UPDATE_CHANNEL, $MOZ_UPDATE_CHANNEL)
 AC_SUBST(MOZ_UPDATE_CHANNEL)
 
+# Allow to specify a Google API key file that contains the secret key to be
+# used for various Google API requests.
+MOZ_ARG_WITH_STRING(google-api-keyfile,
+[  --with-google-api-keyfile=file   Use the secret key contained in the given keyfile for Google API requests],
+  MOZ_GOOGLE_API_KEY=`cat $withval`)
+if test -z "$MOZ_GOOGLE_API_KEY"; then
+    MOZ_GOOGLE_API_KEY=no-google-api-key
+fi
+AC_DEFINE_UNQUOTED(MOZ_GOOGLE_API_KEY, $MOZ_GOOGLE_API_KEY)
+
 # Allow the application to influence configure with a confvars.sh script.
 AC_MSG_CHECKING([if app-specific confvars.sh exists])
 if test -f "${srcdir}/${MOZ_BUILD_APP}/confvars.sh" ; then
   AC_MSG_RESULT([${srcdir}/${MOZ_BUILD_APP}/confvars.sh])
   . "${srcdir}/${MOZ_BUILD_APP}/confvars.sh"
 else
   AC_MSG_RESULT([no])
 fi
--- a/dom/src/geolocation/nsGeolocation.cpp
+++ b/dom/src/geolocation/nsGeolocation.cpp
@@ -390,21 +390,20 @@ nsGeolocationRequest::Cancel()
 
 NS_IMETHODIMP
 nsGeolocationRequest::Allow()
 {
   nsCOMPtr<nsIDOMWindow> window;
   GetWindow(getter_AddRefs(window));
   nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(window);
   nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
-  bool isPrivate = loadContext && loadContext->UsePrivateBrowsing();
 
   // Kick off the geo device, if it isn't already running
   nsRefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
-  nsresult rv = gs->StartDevice(GetPrincipal(), isPrivate);
+  nsresult rv = gs->StartDevice(GetPrincipal());
 
   if (NS_FAILED(rv)) {
     // Location provider error
     NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE);
     return NS_OK;
   }
 
   nsCOMPtr<nsIDOMGeoPosition> lastPosition = gs->GetCachedPosition();
@@ -792,17 +791,17 @@ nsGeolocationService::SetCachedPosition(
 
 nsIDOMGeoPosition*
 nsGeolocationService::GetCachedPosition()
 {
   return mLastPosition;
 }
 
 nsresult
-nsGeolocationService::StartDevice(nsIPrincipal *aPrincipal, bool aRequestPrivate)
+nsGeolocationService::StartDevice(nsIPrincipal *aPrincipal)
 {
   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
@@ -823,17 +822,17 @@ nsGeolocationService::StartDevice(nsIPri
 
   if (!mProvider) {
     return NS_ERROR_FAILURE;
   }
 
   nsresult rv;
 
   if (NS_FAILED(rv = mProvider->Startup()) ||
-      NS_FAILED(rv = mProvider->Watch(this, aRequestPrivate))) {
+      NS_FAILED(rv = mProvider->Watch(this))) {
 
     NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE);
     return rv;
   }
 
   obs->NotifyObservers(mProvider,
                        "geolocation-device-events",
                        NS_LITERAL_STRING("starting").get());
--- a/dom/src/geolocation/nsGeolocation.h
+++ b/dom/src/geolocation/nsGeolocation.h
@@ -125,17 +125,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, bool aRequestPrivate);
+  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
--- a/dom/system/NetworkGeolocationProvider.js
+++ b/dom/system/NetworkGeolocationProvider.js
@@ -1,30 +1,24 @@
 /* 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/. */
 
-
-// Do not use this API without permission from Google.
-// See http://www.google.com/support/enterprise/bin/request.py?contact_type=gme&utm_campaign=en-us-ptr-mz
-// for more information.
+// See https://developers.google.com/maps/documentation/business/geolocation/
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 const Ci = Components.interfaces;
 const Cc = Components.classes;
 
 let gLoggingEnabled = false;
 let gTestingEnabled = false;
 let gUseScanning = true;
 
-let gPrivateAccessToken = '';
-let gPrivateAccessTime = 0;
-
 function LOG(aMsg) {
   if (gLoggingEnabled)
   {
     aMsg = "*** WIFI GEO: " + aMsg + "\n";
     Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(aMsg);
     dump(aMsg);
   }
 }
@@ -57,21 +51,16 @@ WifiGeoPositionObject.prototype = {
   QueryInterface:   XPCOMUtils.generateQI([Ci.nsIDOMGeoPosition]),
 
   // Class Info is required to be able to pass objects back into the DOM.
   classInfo: XPCOMUtils.generateCI({interfaces: [Ci.nsIDOMGeoPosition],
                                     flags: Ci.nsIClassInfo.DOM_OBJECT,
                                     classDescription: "wifi geo location position object"}),
 };
 
-function privateBrowsingObserver(aSubject, aTopic, aData) {
-  gPrivateAccessToken = '';
-  gPrivateAccessTime = 0;
-}
-
 function WifiGeoPositionProvider() {
   try {
     gLoggingEnabled = Services.prefs.getBoolPref("geo.wifi.logging.enabled");
   } catch (e) {}
 
   try {
     gTestingEnabled = Services.prefs.getBoolPref("geo.wifi.testing");
   } catch (e) {}
@@ -79,19 +68,16 @@ 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.lastRequestPrivate = false;
-
-  Services.obs.addObserver(privateBrowsingObserver, "last-pb-context-exited", false);
 }
 
 WifiGeoPositionProvider.prototype = {
   classID:          Components.ID("{77DA64D3-7458-4920-9491-86CC9914F904}"),
   QueryInterface:   XPCOMUtils.generateQI([Ci.nsIGeolocationProvider,
                                            Ci.nsIWifiListener,
                                            Ci.nsITimerCallback]),
   startup:  function() {
@@ -107,223 +93,117 @@ WifiGeoPositionProvider.prototype = {
     // always sending data.  It doesn't matter if we have an access point or not.
     this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
     if (!gTestingEnabled)
       this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT);
     else
       this.timer.initWithCallback(this, 200, this.timer.TYPE_REPEATING_SLACK);
   },
 
-  watch: function(c, requestPrivate) {
+  watch: function(c) {
     LOG("watch called");
 
     if (!this.wifiService && gUseScanning) {
       this.wifiService = Cc["@mozilla.org/wifi/monitor;1"].getService(Components.interfaces.nsIWifiMonitor);
       this.wifiService.startWatching(this);
-      this.lastRequestPrivate = requestPrivate;
     }
     if (this.hasSeenWiFi) {
       this.hasSeenWiFi = false;
       if (gUseScanning) {
         this.wifiService.stopWatching(this);
         this.wifiService.startWatching(this);
       } else {
         // For testing situations, ensure that we always trigger an update.
         this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT);
       }
-      this.lastRequestPrivate = requestPrivate;
     }
   },
 
   shutdown: function() { 
     LOG("shutdown called");
     if(this.wifiService) {
       this.wifiService.stopWatching(this);
       this.wifiService = null;
     }
     if (this.timer != null) {
       this.timer.cancel();
       this.timer = null;
     }
 
-    // Although we aren't using cookies, we should err on the side of not
-    // saving any access tokens if the user asked us not to save cookies or
-    // has changed the lifetimePolicy.  The access token in these cases is
-    // used and valid for the life of this object (eg. between startup and
-    // shutdown).
-    if (Services.prefs.getIntPref("network.cookie.lifetimePolicy") != 0)
-      Services.prefs.deleteBranch("geo.wifi.access_token.");
     this.started = false;
   },
 
   setHighAccuracy: function(enable) {
   },
 
-  getAccessTokenForURL: function(url)
-  {
-    // check to see if we have an access token:
-    let accessToken = "";
-    try {
-      if (this.lastRequestPrivate) {
-        accessToken = gPrivateAccessToken;
-      } else {
-        let accessTokenPrefName = "geo.wifi.access_token." + url;
-        accessToken = Services.prefs.getCharPref(accessTokenPrefName);
-      }
-
-      // check to see if it has expired
-      let accessTokenDate;
-      if (this.lastRequestPrivate) {
-        accessTokenDate = gPrivateAccessTime;
-      } else {
-        accessTokenDate = Services.prefs.getIntPref(accessTokenPrefName + ".time");
-      }
-      
-      let accessTokenInterval = 1209600;  // seconds in 2 weeks
-      try {
-        accessTokenInterval = Services.prefs.getIntPref("geo.wifi.access_token.recycle_interval");
-      } catch (e) {}
-            
-      if ((Date.now() / 1000) - accessTokenDate > accessTokenInterval)
-        accessToken = "";
-    }
-    catch (e) {
-      accessToken = "";
-    }
-    return accessToken;
-  },
-
   onChange: function(accessPoints) {
     LOG("onChange called");
     this.hasSeenWiFi = true;
 
-    let providerUrlBase = "https://maps.googleapis.com/maps/api/browserlocation/json";
-    try {
-        providerUrlBase = Services.prefs.getCharPref("geo.wifi.uri");      
-    } catch (x) {};
-    let providerUrl;
+    let url = Services.urlFormatter.formatURLPref("geo.wifi.uri");
 
-    let query = providerUrlBase.indexOf("?");
-    if (query == -1)
-      providerUrl = providerUrlBase + "?"
-    else
-      providerUrl = providerUrlBase + "&";
-    providerUrl = providerUrl + "browser=firefox&sensor=true";
-    
+    function isPublic(ap) {
+        let mask = "_nomap"
+        let result = ap.ssid.indexOf(mask, ap.ssid.length - mask.length) == -1;
+        if (result != -1) {
+            LOG("Filtering out " + ap.ssid);
+        }
+        return result;
+    };
 
-    let accessToken = this.getAccessTokenForURL(providerUrlBase);
-    if (accessToken !== "")
-      providerUrl = providerUrl + "&access_token="+accessToken;
-
-    function bySignal(a, b) {
+    function sort(a, b) {
       return b.signal - a.signal;
     };
 
-    function noOptOut(ap) {
-      let optOut = (ap.ssid === "" || ap.ssid.endsWith("_nomap"));
-      return !optOut;
-    };
-
     function encode(ap) {
-      // make sure that the ssid doesn't contain any | chars.
-      ap.ssid = ap.ssid.replace("|", "\\|");
-      // gls service parses the | as fields
-      return "&wifi=mac:"+ap.mac+"|ssid:"+ap.ssid+"|ss:"+ap.signal;
+      return { 'macAddress': ap.mac, 'signalStrength': ap.signal }; 
     };
 
+    var data;
     if (accessPoints) {
-        providerUrl += accessPoints.filter(noOptOut)
-                                   .sort(bySignal)
-                                   .map(encode)
-                                   .join("");
+        data = JSON.stringify({wifiAccessPoints: accessPoints.filter(isPublic).sort(sort).map(encode)})
     }
 
-    providerUrl = encodeURI(providerUrl);
-
-    // max length is 2k.  make sure we are under that
-    let x = providerUrl.length - 2000;
-    if (x >= 0) {
-	// we need to trim
-	let doomed = providerUrl.lastIndexOf("&", 2000);
-	LOG("Doomed:"+doomed);
-	providerUrl = providerUrl.substring(0, doomed);
-    }
-    
-    LOG("************************************* Sending request:\n" + providerUrl + "\n");
+    LOG("************************************* Sending request:\n" + url + "\n");
 
     // send our request to a wifi geolocation network provider:
     let xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
                         .createInstance(Ci.nsIXMLHttpRequest);
 
     // This is a background load
+  
+    xhr.open("POST", url, true);
+    xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
+    xhr.responseType = "json";
     xhr.mozBackgroundRequest = true;
-    xhr.open("GET", providerUrl, true);
     xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
-    xhr.addEventListener("error", function(req) {
-        LOG("onerror: " + req);
-    }, false);
-    xhr.addEventListener("load", function (req) {  
-        LOG("service returned: " + req.target.responseText);
-        response = JSON.parse(req.target.responseText);
-        /*
-          {
-            "status": "OK",
-            "accuracy": 150.0,
-            "location": {
-              "lat": -33.85702,
-              "lng": 151.21494
-            },
-            "access_token": "quijibo"
-          }
-        */
+    xhr.onerror = function() {
+        LOG("onerror: " + xhr);
+    };
 
-        if (response.status != "OK")
-          return;
-
-        if (response.location) {
-          let newLocation = new WifiGeoPositionObject(response.location.lat,
-                                                      response.location.lng,
-                                                      response.accuracy);
-
-          let update = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate);
-          update.update(newLocation);
+    xhr.onload = function() {  
+        LOG("gls returned status: " + xhr.status + " --> " +  JSON.stringify(xhr.response));
+        if (xhr.status != 200) {
+            return;
         }
 
-        // Check to see if we have a new access token
-        let newAccessToken = response.access_token;
-        if (newAccessToken !== undefined)
-        {
-          let accessToken = "";
-          let accessTokenPrefName = "geo.wifi.access_token." + providerUrlBase;
-          if (this.lastRequestPrivate) {
-            accessTokenPrefName = gPrivateAccessToken;
-          } else {
-            try { accessToken = Services.prefs.getCharPref(accessTokenPrefName); } catch (e) {}
-          }
+        if (!xhr.response.location) {
+            return;
+        }
 
-          if (accessToken != newAccessToken) {
-            // no match, lets cache
-            LOG("New Access Token: " + newAccessToken + "\n" + accessTokenPrefName);
-            if (this.lastRequestPrivate) {
-              gPrivateAccessToken = newAccessToken;
-              gPrivateAccessTime = nowInSeconds();
-            } else {
-              try {
-                Services.prefs.setIntPref(accessTokenPrefName + ".time", nowInSeconds());
-                Services.prefs.setCharPref(accessTokenPrefName, newAccessToken);
-              } catch (x) {
-                  // XXX temporary hack for bug 575346 to allow geolocation to function
-              }
-            }
-          }
-        }
-    }, false);
+        let newLocation = new WifiGeoPositionObject(xhr.response.location.lat,
+                                                    xhr.response.location.lng,
+                                                    xhr.response.accuracy);
+        
+        Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate)
+            .update(newLocation);
+    };
 
-    LOG("************************************* ------>>>> sending.");
-    xhr.send(null);
+    LOG("************************************* ------>>>> sending " + data);
+    xhr.send(data);
   },
 
   onError: function (code) {
     LOG("wifi error: " + code);
   },
 
   notify: function (timer) {
     if (gTestingEnabled || !gUseScanning) {
--- a/dom/system/android/AndroidLocationProvider.cpp
+++ b/dom/system/android/AndroidLocationProvider.cpp
@@ -28,17 +28,17 @@ AndroidLocationProvider::Startup()
 {
     if (!AndroidBridge::Bridge())
         return NS_ERROR_NOT_IMPLEMENTED;
     AndroidBridge::Bridge()->EnableLocation(true);
     return NS_OK;
 }
 
 NS_IMETHODIMP
-AndroidLocationProvider::Watch(nsIGeolocationUpdate* aCallback, bool aRequestPrivate)
+AndroidLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
 {
     NS_IF_RELEASE(gLocationCallback);
     gLocationCallback = aCallback;
     NS_IF_ADDREF(gLocationCallback);
     return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp
+++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
@@ -597,17 +597,17 @@ GonkGPSGeolocationProvider::Startup()
   mInitThread->Dispatch(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::Init),
                         NS_DISPATCH_NORMAL);
 
   mStarted = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-GonkGPSGeolocationProvider::Watch(nsIGeolocationUpdate* aCallback, bool aPrivate)
+GonkGPSGeolocationProvider::Watch(nsIGeolocationUpdate* aCallback)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   mLocationCallback = aCallback;
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/system/unix/MaemoLocationProvider.cpp
+++ b/dom/system/unix/MaemoLocationProvider.cpp
@@ -196,17 +196,17 @@ NS_IMETHODIMP MaemoLocationProvider::Sta
     return NS_ERROR_FAILURE;
 
   if (update)
     mUpdateTimer->InitWithCallback(this, update, nsITimer::TYPE_REPEATING_SLACK);
 
   return NS_OK;
 }
 
-NS_IMETHODIMP MaemoLocationProvider::Watch(nsIGeolocationUpdate *callback, bool aRequestPrivate)
+NS_IMETHODIMP MaemoLocationProvider::Watch(nsIGeolocationUpdate *callback)
 {
   if (mCallback)
     return NS_OK;
 
   mCallback = callback;
   return NS_OK;
 }
 
--- a/dom/system/unix/QTMLocationProvider.cpp
+++ b/dom/system/unix/QTMLocationProvider.cpp
@@ -58,17 +58,17 @@ QTMLocationProvider::Startup()
         return NS_ERROR_NOT_IMPLEMENTED;
 
     mLocation->startUpdates();
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
-QTMLocationProvider::Watch(nsIGeolocationUpdate* aCallback, bool aRequestPrivate)
+QTMLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
 {
     mCallback = aCallback;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 QTMLocationProvider::Shutdown()
--- a/mobile/android/modules/Sanitizer.jsm
+++ b/mobile/android/modules/Sanitizer.jsm
@@ -87,22 +87,16 @@ Sanitizer.prototype = {
         return true;
       }
     },
 
     cookies: {
       clear: function ()
       {
         Services.cookies.removeAll();
-
-        // clear any network geolocation provider sessions
-        try {
-          var branch = Services.prefs.getBranch("geo.wifi.access_token.");
-          branch.deleteBranch("");
-        } catch (e) {dump(e);}
       },
 
       get canClear()
       {
         return true;
       }
     },
 
--- a/toolkit/components/urlformatter/Makefile.in
+++ b/toolkit/components/urlformatter/Makefile.in
@@ -7,12 +7,11 @@ DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 DISABLED_EXTRA_COMPONENTS = \
   nsURLFormatter.manifest \
-  nsURLFormatter.js \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/components/urlformatter/moz.build
+++ b/toolkit/components/urlformatter/moz.build
@@ -8,11 +8,14 @@ TEST_DIRS += ['tests']
 
 XPIDL_SOURCES += [
     'nsIURLFormatter.idl',
 ]
 
 MODULE = 'urlformatter'
 
 EXTRA_COMPONENTS += [
-    'nsURLFormatter.js',
     'nsURLFormatter.manifest',
 ]
+
+EXTRA_PP_COMPONENTS += [
+    'nsURLFormatter.js',
+]
--- a/toolkit/components/urlformatter/nsURLFormatter.js
+++ b/toolkit/components/urlformatter/nsURLFormatter.js
@@ -1,8 +1,10 @@
+#filter substitution
+
 /* 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/. */
 
  /**
  * @class nsURLFormatterService
  *
  * nsURLFormatterService exposes methods to substitute variables in URL formats.
@@ -96,16 +98,17 @@ nsURLFormatterService.prototype = {
     PLATFORMVERSION:  function() this.appInfo.platformVersion,
     PLATFORMBUILDID:  function() this.appInfo.platformBuildID,
     APP:              function() this.appInfo.name.toLowerCase().replace(/ /, ""),
     OS:               function() this.appInfo.OS,
     XPCOMABI:         function() this.ABI,
     BUILD_TARGET:     function() this.appInfo.OS + "_" + this.ABI,
     OS_VERSION:       function() this.OSVersion,
     CHANNEL:          function() UpdateChannel.get(),
+    GOOGLE_API_KEY:   function() "@MOZ_GOOGLE_API_KEY@",
     DISTRIBUTION:     function() this.distribution.id,
     DISTRIBUTION_VERSION: function() this.distribution.version
   },
 
   formatURL: function uf_formatURL(aFormat) {
     var _this = this;
     var replacementCallback = function(aMatch, aKey) {
       if (aKey in _this._defaults) {
--- a/toolkit/forgetaboutsite/ForgetAboutSite.jsm
+++ b/toolkit/forgetaboutsite/ForgetAboutSite.jsm
@@ -36,21 +36,16 @@ function hasRootDomain(str, aDomain)
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 this.ForgetAboutSite = {
   removeDataFromDomain: function CRH_removeDataFromDomain(aDomain)
   {
-    // clear any and all network geolocation provider sessions
-    try {
-        Services.prefs.deleteBranch("geo.wifi.access_token.");
-    } catch (e) {}
-
     PlacesUtils.history.removePagesFromHost(aDomain, true);
 
     // Cache
     let (cs = Cc["@mozilla.org/network/cache-service;1"].
               getService(Ci.nsICacheService)) {
       // NOTE: there is no way to clear just that domain, so we clear out
       //       everything)
       try {
--- a/xpcom/system/nsIGeolocationProvider.idl
+++ b/xpcom/system/nsIGeolocationProvider.idl
@@ -42,33 +42,30 @@ interface nsIGeolocationUpdate : nsISupp
 
 
 /**
  * Interface provides location information to the nsGeolocator
  * via the nsIDOMGeolocationCallback interface.  After
  * startup is called, any geo location change should call
  * callback.update().
  */
-[scriptable, uuid(d32b87b3-fe96-4f42-81ab-2f39f7ec43ff)]
+[scriptable, uuid(AC4A133B-9F92-4F7C-B369-D40CB6B17650)]
 interface nsIGeolocationProvider : nsISupports {
 
   /**
    * Start up the provider.  This is called before any other
    * method.  may be called multiple times.
    */
   void startup();
 
   /**
    * watch
-   * When a location change is observed, notify the callback. The privacy
-   * argument informs the provider whether the initiating request came from
-   * a private context; it is up to the provider to use that information
-   * in a sensible manner.
+   * When a location change is observed, notify the callback.
    */
-  void watch(in nsIGeolocationUpdate callback, in boolean requestPrivate);
+  void watch(in nsIGeolocationUpdate callback);
 
   /**
    * shutdown
    * Shuts down the location device.
    */
   void shutdown();
 
   /**