Bug 882485 - Add API keys support for Google Location Service API. r=gps, jdm, gavin. sr=brendan

This commit is contained in:
Doug Turner 2013-06-12 19:20:07 -07:00
Родитель 94571819d4
Коммит 56ec59c248
17 изменённых файлов: 70 добавлений и 205 удалений

Просмотреть файл

@ -1273,3 +1273,6 @@ pref("media.webaudio.enabled", true);
// 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%");

Просмотреть файл

@ -177,15 +177,6 @@ Sanitizer.prototype = {
}
}
}
// 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()

Просмотреть файл

@ -100,15 +100,6 @@ Sanitizer.prototype = {
{
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()

Просмотреть файл

@ -4332,6 +4332,16 @@ 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

Просмотреть файл

@ -395,11 +395,10 @@ nsGeolocationRequest::Allow()
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
@ -797,7 +796,7 @@ nsGeolocationService::GetCachedPosition()
}
nsresult
nsGeolocationService::StartDevice(nsIPrincipal *aPrincipal, bool aRequestPrivate)
nsGeolocationService::StartDevice(nsIPrincipal *aPrincipal)
{
if (!sGeoEnabled || sGeoInitPending) {
return NS_ERROR_NOT_AVAILABLE;
@ -828,7 +827,7 @@ nsGeolocationService::StartDevice(nsIPrincipal *aPrincipal, bool aRequestPrivate
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;

Просмотреть файл

@ -130,7 +130,7 @@ public:
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();

Просмотреть файл

@ -2,10 +2,7 @@
* 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");
@ -17,9 +14,6 @@ let gLoggingEnabled = false;
let gTestingEnabled = false;
let gUseScanning = true;
let gPrivateAccessToken = '';
let gPrivateAccessTime = 0;
function LOG(aMsg) {
if (gLoggingEnabled)
{
@ -62,11 +56,6 @@ WifiGeoPositionObject.prototype = {
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");
@ -84,9 +73,6 @@ function WifiGeoPositionProvider() {
this.timer = null;
this.hasSeenWiFi = false;
this.started = false;
this.lastRequestPrivate = false;
Services.obs.addObserver(privateBrowsingObserver, "last-pb-context-exited", false);
}
WifiGeoPositionProvider.prototype = {
@ -112,13 +98,12 @@ WifiGeoPositionProvider.prototype = {
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;
@ -129,7 +114,6 @@ WifiGeoPositionProvider.prototype = {
// For testing situations, ensure that we always trigger an update.
this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT);
}
this.lastRequestPrivate = requestPrivate;
}
},
@ -144,181 +128,77 @@ WifiGeoPositionProvider.prototype = {
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 (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
}
}
}
if (!xhr.response.location) {
return;
}
}, false);
LOG("************************************* ------>>>> sending.");
xhr.send(null);
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 " + data);
xhr.send(data);
},
onError: function (code) {

Просмотреть файл

@ -33,7 +33,7 @@ AndroidLocationProvider::Startup()
}
NS_IMETHODIMP
AndroidLocationProvider::Watch(nsIGeolocationUpdate* aCallback, bool aRequestPrivate)
AndroidLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
{
NS_IF_RELEASE(gLocationCallback);
gLocationCallback = aCallback;

Просмотреть файл

@ -602,7 +602,7 @@ GonkGPSGeolocationProvider::Startup()
}
NS_IMETHODIMP
GonkGPSGeolocationProvider::Watch(nsIGeolocationUpdate* aCallback, bool aPrivate)
GonkGPSGeolocationProvider::Watch(nsIGeolocationUpdate* aCallback)
{
MOZ_ASSERT(NS_IsMainThread());

Просмотреть файл

@ -201,7 +201,7 @@ NS_IMETHODIMP MaemoLocationProvider::Startup()
return NS_OK;
}
NS_IMETHODIMP MaemoLocationProvider::Watch(nsIGeolocationUpdate *callback, bool aRequestPrivate)
NS_IMETHODIMP MaemoLocationProvider::Watch(nsIGeolocationUpdate *callback)
{
if (mCallback)
return NS_OK;

Просмотреть файл

@ -63,7 +63,7 @@ QTMLocationProvider::Startup()
}
NS_IMETHODIMP
QTMLocationProvider::Watch(nsIGeolocationUpdate* aCallback, bool aRequestPrivate)
QTMLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
{
mCallback = aCallback;

Просмотреть файл

@ -92,12 +92,6 @@ Sanitizer.prototype = {
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()

Просмотреть файл

@ -12,7 +12,6 @@ include $(DEPTH)/config/autoconf.mk
DISABLED_EXTRA_COMPONENTS = \
nsURLFormatter.manifest \
nsURLFormatter.js \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -13,6 +13,9 @@ XPIDL_SOURCES += [
MODULE = 'urlformatter'
EXTRA_COMPONENTS += [
'nsURLFormatter.js',
'nsURLFormatter.manifest',
]
EXTRA_PP_COMPONENTS += [
'nsURLFormatter.js',
]

Просмотреть файл

@ -1,3 +1,5 @@
#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/. */
@ -101,6 +103,7 @@ nsURLFormatterService.prototype = {
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
},

Просмотреть файл

@ -41,11 +41,6 @@ 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

Просмотреть файл

@ -47,7 +47,7 @@ interface nsIGeolocationUpdate : nsISupports {
* 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 {
/**
@ -58,12 +58,9 @@ interface nsIGeolocationProvider : nsISupports {
/**
* 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