summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeeshan Ali (Khattak) <zeeshanak@gnome.org>2016-02-18 16:43:23 +0000
committerZeeshan Ali (Khattak) <zeeshanak@gnome.org>2016-02-18 18:01:58 +0000
commit64e11c38b44712eeb9cb2b3a69a30f18713d268f (patch)
treeeefc0f7d7da670f6d1b7b16bae9f03221a194846
parent2d3ea8b38837d7c54e67cafa5f9c27db4734a848 (diff)
downloadgnome-control-center-wip/loc-apps.tar.gz
privacy: Per-app location access controlwip/loc-apps
-rw-r--r--panels/privacy/cc-privacy-panel.c174
-rw-r--r--panels/privacy/privacy.ui54
2 files changed, 222 insertions, 6 deletions
diff --git a/panels/privacy/cc-privacy-panel.c b/panels/privacy/cc-privacy-panel.c
index 7edf26b55..94666935d 100644
--- a/panels/privacy/cc-privacy-panel.c
+++ b/panels/privacy/cc-privacy-panel.c
@@ -21,6 +21,7 @@
#include "shell/list-box-helper.h"
#include "cc-privacy-panel.h"
#include "cc-privacy-resources.h"
+#include "cc-util.h"
#include <gio/gdesktopappinfo.h>
#include <glib/gi18n.h>
@@ -38,6 +39,9 @@ CC_PANEL_REGISTER (CcPrivacyPanel, cc_privacy_panel)
#define REPORT_TECHNICAL_PROBLEMS "report-technical-problems"
#define LOCATION_ENABLED "enabled"
+#define APP_PERMISSIONS_TABLE "desktop"
+#define APP_PERMISSIONS_ID "geolocation"
+
struct _CcPrivacyPanelPrivate
{
GtkBuilder *builder;
@@ -48,6 +52,9 @@ struct _CcPrivacyPanelPrivate
GtkWidget *trash_dialog;
GtkWidget *software_dialog;
GtkWidget *list_box;
+ GtkWidget *location_apps_list_box;
+ GtkWidget *location_apps_label;
+ GtkWidget *location_apps_frame;
GSettings *lockdown_settings;
GSettings *lock_settings;
@@ -60,6 +67,9 @@ struct _CcPrivacyPanelPrivate
guint abrt_watch_id;
GDBusProxy *gclue_manager;
+ GDBusProxy *perm_store;
+
+ GtkSizeGroup *location_icon_size_group;
};
static char *
@@ -455,6 +465,151 @@ on_gclue_manager_ready (GObject *source_object,
}
static void
+add_location_app (CcPrivacyPanel *self,
+ const gchar *app_id,
+ gboolean enabled,
+ gint64 last_used)
+{
+ GDesktopAppInfo *app_info;
+ char *desktop_id;
+ GtkWidget *box, *row, *w;
+ GIcon *icon;
+ GDateTime *t;
+ char *last_used_str;
+
+ desktop_id = g_strjoin (".", app_id, "desktop", NULL);
+ app_info = g_desktop_app_info_new (desktop_id);
+ if (app_info == NULL)
+ return;
+
+ row = gtk_list_box_row_new ();
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_widget_set_margin_top (box, 6);
+ gtk_widget_set_margin_bottom (box, 6);
+ gtk_container_add (GTK_CONTAINER (row), box);
+ gtk_widget_set_hexpand (box, TRUE);
+ gtk_container_add (GTK_CONTAINER (self->priv->location_apps_list_box), row);
+
+ icon = g_app_info_get_icon (G_APP_INFO (app_info));
+ w = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_LARGE_TOOLBAR);
+ gtk_widget_set_margin_start (w, 12);
+ gtk_widget_set_halign (w, GTK_ALIGN_CENTER);
+ gtk_widget_set_valign (w, GTK_ALIGN_CENTER);
+ gtk_size_group_add_widget (self->priv->location_icon_size_group, w);
+ gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
+
+ w = gtk_label_new (g_app_info_get_name (G_APP_INFO (app_info)));
+ gtk_widget_set_margin_start (w, 12);
+ gtk_widget_set_margin_end (w, 12);
+ gtk_widget_set_halign (w, GTK_ALIGN_START);
+ gtk_widget_set_valign (w, GTK_ALIGN_CENTER);
+ gtk_label_set_xalign (GTK_LABEL (w), 0);
+ gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
+
+ t = g_date_time_new_from_unix_utc (last_used);
+ last_used_str = cc_util_get_smart_date (t);
+ w = gtk_label_new (last_used_str);
+ g_free (last_used_str);
+ gtk_style_context_add_class (gtk_widget_get_style_context (w), "dim-label");
+ gtk_widget_set_margin_start (w, 12);
+ gtk_widget_set_margin_end (w, 12);
+ gtk_widget_set_halign (w, GTK_ALIGN_END);
+ gtk_widget_set_valign (w, GTK_ALIGN_CENTER);
+ gtk_box_pack_start (GTK_BOX (box), w, TRUE, TRUE, 0);
+
+ w = gtk_switch_new ();
+ gtk_switch_set_active (GTK_SWITCH (w), enabled);
+ gtk_widget_set_margin_end (w, 12);
+ gtk_widget_set_halign (w, GTK_ALIGN_END);
+ gtk_widget_set_valign (w, GTK_ALIGN_CENTER);
+ gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (row);
+}
+
+static void
+on_perm_store_lookup_done(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ CcPrivacyPanel *self = CC_PRIVACY_PANEL (user_data);
+ GVariant *results, *dict;
+ GVariantIter iter;
+ gchar *key;
+ gchar **value;
+ GList *children;
+ GError *error = NULL;
+
+ results = g_dbus_proxy_call_finish (self->priv->perm_store,
+ res,
+ &error);
+ if (error != NULL)
+ {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+
+ return;
+ }
+
+ dict = g_variant_get_child_value (results, 0);
+ g_variant_iter_init (&iter, dict);
+ while (g_variant_iter_loop (&iter, "{s^as}", &key, &value))
+ {
+ gboolean enabled;
+ gint64 last_used;
+
+ if (g_strv_length (value) < 3)
+ continue;
+
+ enabled = (g_strcmp0 (value[0], "NONE") != 0);
+ last_used = g_ascii_strtoll (value[2], NULL, 10);
+ add_location_app (self,
+ key,
+ enabled,
+ last_used);
+ }
+
+ children = gtk_container_get_children (GTK_CONTAINER (self->priv->location_apps_list_box));
+ if (g_list_length (children) > 0)
+ {
+ gtk_widget_set_visible (self->priv->location_apps_label, TRUE);
+ gtk_widget_set_visible (self->priv->location_apps_frame, TRUE);
+ }
+ g_list_free (children);
+}
+
+static void
+on_perm_store_ready (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ CcPrivacyPanel *self = CC_PRIVACY_PANEL (user_data);
+ GVariant *params;
+ GError *error = NULL;
+
+ self->priv->perm_store = g_dbus_proxy_new_for_bus_finish (res, &error);
+ if (error != NULL)
+ {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+
+ return;
+ }
+
+ params = g_variant_new ("(ss)",
+ APP_PERMISSIONS_TABLE,
+ APP_PERMISSIONS_ID);
+ g_dbus_proxy_call (self->priv->perm_store,
+ "Lookup",
+ params,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ on_perm_store_lookup_done,
+ self);
+}
+
+static void
add_location (CcPrivacyPanel *self)
{
CcPrivacyPanelPrivate *priv = self->priv;
@@ -491,6 +646,16 @@ add_location (CcPrivacyPanel *self)
NULL,
on_gclue_manager_ready,
self);
+
+ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "org.freedesktop.XdgApp",
+ "/org/freedesktop/XdgApp/PermissionStore",
+ "org.freedesktop.XdgApp.PermissionStore",
+ NULL,
+ on_perm_store_ready,
+ self);
}
static void
@@ -892,6 +1057,8 @@ cc_privacy_panel_finalize (GObject *object)
g_clear_object (&priv->notification_settings);
g_clear_object (&priv->location_settings);
g_clear_object (&priv->gclue_manager);
+ g_clear_object (&priv->perm_store);
+ g_clear_object (&priv->location_icon_size_group);
G_OBJECT_CLASS (cc_privacy_panel_parent_class)->finalize (object);
}
@@ -963,6 +1130,13 @@ cc_privacy_panel_init (CcPrivacyPanel *self)
gtk_container_add (GTK_CONTAINER (frame), widget);
self->priv->list_box = widget;
gtk_widget_show (widget);
+ self->priv->location_apps_list_box = WID ("location_apps_list_box");
+ gtk_list_box_set_header_func (GTK_LIST_BOX (self->priv->location_apps_list_box),
+ cc_list_box_update_header_func,
+ NULL, NULL);
+ self->priv->location_apps_frame = WID ("location_apps_frame");
+ self->priv->location_apps_label = WID ("location_apps_label");
+ self->priv->location_icon_size_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
g_signal_connect_swapped (widget, "row-activated",
G_CALLBACK (activate_row), self);
diff --git a/panels/privacy/privacy.ui b/panels/privacy/privacy.ui
index 804157cc3..9bc358027 100644
--- a/panels/privacy/privacy.ui
+++ b/panels/privacy/privacy.ui
@@ -725,23 +725,24 @@ All the information we collect is made anonymous, and we will never share your d
<object class="GtkBox" id="location-vbox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
+ <property name="margin_start">12</property>
+ <property name="margin_end">12</property>
<property name="spacing">2</property>
<child>
<object class="GtkLabel" id="location_description_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="margin_start">12</property>
- <property name="margin_end">12</property>
- <property name="margin_top">6</property>
+ <property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="label" translatable="yes">Location services allow applications to determine your geographical position. Accuracy is increased by enabling WiFi and GPS.</property>
<property name="wrap">True</property>
<property name="max_width_chars">50</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">0</property>
</packing>
</child>
@@ -750,8 +751,6 @@ All the information we collect is made anonymous, and we will never share your d
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="shadow_type">in</property>
- <property name="margin_top">12</property>
- <property name="margin_bottom">12</property>
<child>
<object class="GtkListBox" id="location_listbox">
@@ -815,10 +814,53 @@ All the information we collect is made anonymous, and we will never share your d
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+
+ <child>
+ <object class="GtkLabel" id="location_apps_label">
+ <property name="visible">False</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">24</property>
+ <property name="margin_bottom">12</property>
+ <property name="halign">start</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Applications</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
+ <child>
+ <object class="GtkFrame" id="location_apps_frame">
+ <property name="visible">False</property>
+ <property name="can_focus">False</property>
+ <property name="shadow_type">in</property>
+ <property name="margin_bottom">12</property>
+
+ <child>
+ <object class="GtkListBox" id="location_apps_list_box">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="selection_mode">none</property>
+ </object>
+ </child>
+
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+
</object>
</child>
</object>