modules: Add new geolocation module to handle location access requests

This implements an GeoClue2 agents which gets called whenever an application
tries to access the location resource. It allows the user to allow or deny
this resource to the application.
This commit is contained in:
Stefan Schmidt 2014-11-06 15:54:19 +01:00 committed by Mike Blumenkrantz
parent d424c665b9
commit ef94cfdaba
6 changed files with 221 additions and 0 deletions

View File

@ -965,6 +965,7 @@ AC_E_OPTIONAL_MODULE([wl_fb], $have_wayland, [CHECK_MODULE_WL_FB])
AC_E_OPTIONAL_MODULE([wl_drm], $have_wayland, [CHECK_MODULE_WL_DRM])
#AC_E_OPTIONAL_MODULE([wl_screenshot], true, [CHECK_MODULE_WL_SCREENSHOT])
AC_E_OPTIONAL_MODULE([policy_mobile], true)
AC_E_OPTIONAL_MODULE([geolocation], true)
HALT="/sbin/shutdown -h now"
REBOOT="/sbin/shutdown -r now"
@ -1087,6 +1088,7 @@ src/modules/quickaccess/module.desktop
src/modules/teamwork/module.desktop
src/modules/shot/module.desktop
src/modules/backlight/module.desktop
src/modules/geoclue2/module.desktop
src/modules/tasks/module.desktop
src/modules/xkbswitch/module.desktop
src/modules/tiling/module.desktop

View File

@ -121,3 +121,5 @@ include src/modules/Makefile_wl_fb.mk
#include src/modules/Makefile_wl_screenshot.mk
include src/modules/Makefile_policy_mobile.mk
include src/modules/Makefile_geoclue2.mk

View File

@ -0,0 +1,20 @@
EXTRA_DIST += src/modules/geoclue2/module.desktop.in \
src/modules/geoclue2/e-module-geoclue2.edj
if USE_MODULE_GEOLOCATION
geolocationdir = $(MDIR)/geoclue2
geolocation_DATA = src/modules/geoclue2/e-module-geoclue2.edj \
src/modules/geoclue2/module.desktop
geolocationpkgdir = $(MDIR)/geoclue2/$(MODULE_ARCH)
geolocationpkg_LTLIBRARIES = src/modules/geoclue2/module.la
src_modules_geoclue2_module_la_LIBADD = $(MOD_LIBS)
src_modules_geoclue2_module_la_CPPFLAGS = $(MOD_CPPFLAGS)
src_modules_geoclue2_module_la_LDFLAGS = $(MOD_LDFLAGS)
src_modules_geoclue2_module_la_SOURCES = src/modules/geoclue2/e_mod_main.c
PHONIES += geolocation install-geolocation
geolocation: $(geolocationpkg_LTLIBRARIES) $(geolocation_DATA)
install-geolocation: install-geolocationDATA install-geolocationpkgLTLIBRARIES
endif

Binary file not shown.

View File

@ -0,0 +1,190 @@
#include "e.h"
/* TODO
* o Grey if inUse property is false
* o Blue if the inUse property is true
* o Pulsing if an app requests access and the dialog shows?
* o Dialog with app name and option for Not yet, Never, Only once, Always
* o List of apps in settings window.
* o Display accuracy level? Per app?
*/
/* gadcon requirements */
static E_Gadcon_Client *_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style);
static void _gc_shutdown(E_Gadcon_Client *gcc);
static void _gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient);
static const char *_gc_label(const E_Gadcon_Client_Class *client_class);
static Evas_Object *_gc_icon(const E_Gadcon_Client_Class *client_class, Evas *evas);
static const char *_gc_id_new(const E_Gadcon_Client_Class *client_class);
/* and actually define the gadcon class that this module provides (just 1) */
static const E_Gadcon_Client_Class _gadcon_class =
{
GADCON_CLIENT_CLASS_VERSION,
"geolocation",
{
_gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL, NULL
},
E_GADCON_CLIENT_STYLE_PLAIN
};
/* actual module specifics */
typedef struct _Instance Instance;
struct _Instance
{
E_Gadcon_Client *gcc;
Evas_Object *o_geoclue2;
Eina_Bool in_use;
};
static Eina_List *geoclue2_instances = NULL;
static E_Module *geoclue2_module = NULL;
static void
_geoclue2_cb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
{
Instance *inst = data;
Evas_Event_Mouse_Down *ev = event;
if (ev->button == 3)
{
E_Zone *zone;
E_Menu *m;
E_Menu_Item *mi;
int x, y;
zone = e_util_zone_current_get(e_manager_current_get());
m = e_menu_new();
mi = e_menu_item_new(m);
e_menu_item_label_set(mi, _("Settings"));
e_util_menu_item_theme_icon_set(mi, "configure");
m = e_gadcon_client_util_menu_items_append(inst->gcc, m, 0);
e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon, &x, &y, NULL, NULL);
e_menu_activate_mouse(m, zone, x + ev->output.x, y + ev->output.y,
1, 1, E_MENU_POP_DIRECTION_AUTO, ev->timestamp);
evas_event_feed_mouse_up(inst->gcc->gadcon->evas, ev->button,
EVAS_BUTTON_NONE, ev->timestamp, NULL);
}
}
static E_Gadcon_Client *
_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
{
Evas_Object *o;
E_Gadcon_Client *gcc;
Instance *inst;
inst = E_NEW(Instance, 1);
o = edje_object_add(gc->evas);
e_theme_edje_object_set(o, "base/theme/modules/geolocation",
"e/modules/geolocation/main");
evas_object_show(o);
gcc = e_gadcon_client_new(gc, name, id, style, o);
gcc->data = inst;
inst->gcc = gcc;
inst->o_geoclue2 = o;
inst->in_use = EINA_FALSE;
evas_object_event_callback_add(inst->o_geoclue2,
EVAS_CALLBACK_MOUSE_DOWN,
_geoclue2_cb_mouse_down,
inst);
geoclue2_instances = eina_list_append(geoclue2_instances, inst);
return gcc;
}
static void
_gc_shutdown(E_Gadcon_Client *gcc)
{
Instance *inst;
inst = gcc->data;
geoclue2_instances = eina_list_remove(geoclue2_instances, inst);
evas_object_del(inst->o_geoclue2);
free(inst);
}
static void
_gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient __UNUSED__)
{
Instance *inst;
Evas_Coord mw, mh;
inst = gcc->data;
mw = 0, mh = 0;
edje_object_size_min_get(inst->o_geoclue2, &mw, &mh);
if ((mw < 1) || (mh < 1))
edje_object_size_min_calc(inst->o_geoclue2, &mw, &mh);
if (mw < 4) mw = 4;
if (mh < 4) mh = 4;
e_gadcon_client_aspect_set(gcc, mw, mh);
e_gadcon_client_min_size_set(gcc, mw, mh);
}
static const char *
_gc_label(const E_Gadcon_Client_Class *client_class __UNUSED__)
{
return _("Geolocation");
}
static Evas_Object *
_gc_icon(const E_Gadcon_Client_Class *client_class __UNUSED__, Evas *evas)
{
Evas_Object *o;
char buf[4096];
o = edje_object_add(evas);
snprintf(buf, sizeof(buf), "%s/e-module-geoclue2.edj",
e_module_dir_get(geoclue2_module));
edje_object_file_set(o, buf, "icon");
return o;
}
static const char *
_gc_id_new(const E_Gadcon_Client_Class *client_class)
{
static char buf[4096];
snprintf(buf, sizeof(buf), "%s.%d", client_class->name,
eina_list_count(geoclue2_instances) + 1);
return buf;
}
/* module setup */
EAPI E_Module_Api e_modapi =
{
E_MODULE_API_VERSION,
"Geolocation"
};
EAPI void *
e_modapi_init(E_Module *m)
{
geoclue2_module = m;
e_gadcon_provider_register(&_gadcon_class);
return m;
}
EAPI int
e_modapi_shutdown(E_Module *m __UNUSED__)
{
e_gadcon_provider_unregister(&_gadcon_class);
return 1;
}
EAPI int
e_modapi_save(E_Module *m __UNUSED__)
{
return 1;
}

View File

@ -0,0 +1,7 @@
[Desktop Entry]
Encoding=UTF-8
Type=Link
Name=Geolocation
Comment=Geolocation information
Icon=e-module-geolocation
X-Enlightenment-ModuleType=utils