location: Provide a way to disable geolocation
Now that we are indicating 'geolocation in use' to user, we better also provide at least a way to disable geolocation. Once this is in place, we can provide slightly better controls rather than simply on/off switch. https://bugzilla.gnome.org/show_bug.cgi?id=723684
This commit is contained in:
parent
12ef034b7b
commit
32a49b7846
@ -853,6 +853,7 @@ const AggregateMenu = new Lang.Class({
|
|||||||
if (this._bluetooth) {
|
if (this._bluetooth) {
|
||||||
this.menu.addMenuItem(this._bluetooth.menu);
|
this.menu.addMenuItem(this._bluetooth.menu);
|
||||||
}
|
}
|
||||||
|
this.menu.addMenuItem(this._location.menu);
|
||||||
this.menu.addMenuItem(this._rfkill.menu);
|
this.menu.addMenuItem(this._rfkill.menu);
|
||||||
this.menu.addMenuItem(this._power.menu);
|
this.menu.addMenuItem(this._power.menu);
|
||||||
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
|
@ -1,18 +1,37 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const GLib = imports.gi.GLib;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
|
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
const PanelMenu = imports.ui.panelMenu;
|
const PanelMenu = imports.ui.panelMenu;
|
||||||
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
|
||||||
var GeoclueIface = '<node> \
|
var GeoclueIface = '<node> \
|
||||||
<interface name="org.freedesktop.GeoClue2.Manager"> \
|
<interface name="org.freedesktop.GeoClue2.Manager"> \
|
||||||
<property name="InUse" type="b" access="read"/> \
|
<property name="InUse" type="b" access="read"/> \
|
||||||
|
<property name="AvailableAccuracyLevel" type="u" access="read"/> \
|
||||||
|
<method name="AddAgent"> \
|
||||||
|
<arg name="id" type="s" direction="in"/> \
|
||||||
|
</method> \
|
||||||
</interface> \
|
</interface> \
|
||||||
</node>';
|
</node>';
|
||||||
|
|
||||||
const GeoclueManager = Gio.DBusProxy.makeProxyWrapper(GeoclueIface);
|
const GeoclueManager = Gio.DBusProxy.makeProxyWrapper(GeoclueIface);
|
||||||
|
|
||||||
|
var AgentIface = '<node> \
|
||||||
|
<interface name="org.freedesktop.GeoClue2.Agent"> \
|
||||||
|
<property name="MaxAccuracyLevel" type="u" access="readwrite"/> \
|
||||||
|
<method name="AuthorizeApp"> \
|
||||||
|
<arg name="desktop_id" type="s" direction="in"/> \
|
||||||
|
<arg name="req_accuracy_level" type="u" direction="in"/> \
|
||||||
|
<arg name="authorized" type="b" direction="out"/> \
|
||||||
|
<arg name="allowed_accuracy_level" type="u" direction="out"/> \
|
||||||
|
</method> \
|
||||||
|
</interface> \
|
||||||
|
</node>';
|
||||||
|
|
||||||
const Indicator = new Lang.Class({
|
const Indicator = new Lang.Class({
|
||||||
Name: 'LocationIndicator',
|
Name: 'LocationIndicator',
|
||||||
Extends: PanelMenu.SystemIndicator,
|
Extends: PanelMenu.SystemIndicator,
|
||||||
@ -22,16 +41,58 @@ const Indicator = new Lang.Class({
|
|||||||
|
|
||||||
this._indicator = this._addIndicator();
|
this._indicator = this._addIndicator();
|
||||||
this._indicator.icon_name = 'find-location-symbolic';
|
this._indicator.icon_name = 'find-location-symbolic';
|
||||||
this._sync();
|
this._syncIndicator();
|
||||||
|
|
||||||
|
this._item = new PopupMenu.PopupSubMenuMenuItem(_("Location"), true);
|
||||||
|
this._item.icon.icon_name = 'find-location-symbolic';
|
||||||
|
|
||||||
|
var credentials = new Gio.Credentials();
|
||||||
|
var uid = credentials.get_unix_user();
|
||||||
|
this._agent = Gio.DBusExportedObject.wrapJSObject(AgentIface, this);
|
||||||
|
this._agent.export(Gio.DBus.system,
|
||||||
|
'/org/freedesktop/GeoClue2/Agent/' + uid);
|
||||||
|
|
||||||
|
this._item.status.text = _("On");
|
||||||
|
this._onoffAction = this._item.menu.addAction(_("Turn Off"), Lang.bind(this, this._onOnOffAction));
|
||||||
|
|
||||||
|
this.menu.addMenuItem(this._item);
|
||||||
|
|
||||||
this._watchId = Gio.bus_watch_name(Gio.BusType.SYSTEM,
|
this._watchId = Gio.bus_watch_name(Gio.BusType.SYSTEM,
|
||||||
'org.freedesktop.GeoClue2',
|
'org.freedesktop.GeoClue2',
|
||||||
0,
|
0,
|
||||||
Lang.bind(this, this._connectToGeoclue),
|
Lang.bind(this, this._connectToGeoclue),
|
||||||
Lang.bind(this, this._onGeoclueVanished));
|
Lang.bind(this, this._onGeoclueVanished));
|
||||||
|
|
||||||
|
this._connectToGeoclue();
|
||||||
},
|
},
|
||||||
|
|
||||||
_sync: function() {
|
get MaxAccuracyLevel() {
|
||||||
|
return this._maxAccuracyLevel;
|
||||||
|
},
|
||||||
|
|
||||||
|
set MaxAccuracyLevel(value) {
|
||||||
|
if (this._userSetAccuracy)
|
||||||
|
// If user set the max accuracy level, don't let geoclue override
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._setAccuracy (value, false);
|
||||||
|
},
|
||||||
|
|
||||||
|
// We (and geoclue) have currently no way to reliably identifying apps so
|
||||||
|
// for now, lets just authorize all apps as long as they provide a valid
|
||||||
|
// desktop ID. We also ensure they don't get more accuracy than global max.
|
||||||
|
AuthorizeApp: function(desktop_id, reqAccuracyLevel) {
|
||||||
|
var appSystem = Shell.AppSystem.get_default();
|
||||||
|
var app = appSystem.lookup_app(desktop_id + ".desktop");
|
||||||
|
if (app == null) {
|
||||||
|
return [false, 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var allowedAccuracyLevel = clamp(reqAccuracyLevel, 0, this._maxAccuracyLevel);
|
||||||
|
return [true, allowedAccuracyLevel];
|
||||||
|
},
|
||||||
|
|
||||||
|
_syncIndicator: function() {
|
||||||
if (this._proxy == null) {
|
if (this._proxy == null) {
|
||||||
this._indicator.visible = false;
|
this._indicator.visible = false;
|
||||||
return;
|
return;
|
||||||
@ -53,21 +114,78 @@ const Indicator = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onProxyReady: function (proxy, error) {
|
_onProxyReady: function (proxy, error) {
|
||||||
this._connecting = false;
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
log (error.message);
|
log (error.message);
|
||||||
|
this._userSetAccuracy = false;
|
||||||
|
this._connecting = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._proxy = proxy;
|
this._proxy = proxy;
|
||||||
this._proxy.connect('g-properties-changed', Lang.bind(this, this._sync));
|
this._proxy.connect('g-properties-changed', Lang.bind(this, this._syncIndicator));
|
||||||
|
|
||||||
this._sync();
|
if (!this._availableAccuracyLevel) {
|
||||||
|
this._availableAccuracyLevel = this._proxy.AvailableAccuracyLevel;
|
||||||
|
this._maxAccuracyLevel = this._availableAccuracyLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._syncIndicator();
|
||||||
|
|
||||||
|
this._proxy.AddAgentRemote('gnome-shell', Lang.bind(this, this._onAgentRegistered));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onAgentRegistered: function(result, error) {
|
||||||
|
this._connecting = false;
|
||||||
|
this._notifyMaxAccuracyLevel();
|
||||||
|
|
||||||
|
if (error != null)
|
||||||
|
log (error.message);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onGeoclueVanished: function() {
|
_onGeoclueVanished: function() {
|
||||||
this._proxy = null;
|
this._proxy = null;
|
||||||
|
|
||||||
this._sync();
|
this._syncIndicator();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onOnOffAction: function() {
|
||||||
|
if (this._maxAccuracyLevel == 0)
|
||||||
|
this._setAccuracy (this._availableAccuracyLevel, true);
|
||||||
|
else
|
||||||
|
this._setAccuracy (0, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setAccuracy: function(maxAccuracyLevel, userSet) {
|
||||||
|
this._maxAccuracyLevel = maxAccuracyLevel;
|
||||||
|
|
||||||
|
if (this._maxAccuracyLevel == 0) {
|
||||||
|
this._item.status.text = _("Off");
|
||||||
|
this._onoffAction.label.text = "Turn On";
|
||||||
|
} else {
|
||||||
|
this._item.status.text = _("On");
|
||||||
|
this._onoffAction.label.text = "Turn Off";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userSet)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._userSetAccuracy = true;
|
||||||
|
// Gotta ensure geoclue is up and we are registered as agent to it
|
||||||
|
// before we emit the notify for this property change.
|
||||||
|
if (!this._connectToGeoclue())
|
||||||
|
this._notifyMaxAccuracyLevel();
|
||||||
|
},
|
||||||
|
|
||||||
|
_notifyMaxAccuracyLevel: function() {
|
||||||
|
if (!this._userSetAccuracy)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var variant = new GLib.Variant('u', this._maxAccuracyLevel);
|
||||||
|
this._agent.emit_property_changed ('MaxAccuracyLevel', variant);
|
||||||
|
this._userSetAccuracy = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function clamp(value, min, max) {
|
||||||
|
return Math.max(min, Math.min(max, value));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user