zeitgeist team mailing list archive
-
zeitgeist team
-
Mailing list archive
-
Message #04919
[Merge] lp:~ev/activity-log-manager/whoopsie into lp:activity-log-manager
Evan Dandrea has proposed merging lp:~ev/activity-log-manager/whoopsie into lp:activity-log-manager.
Requested reviews:
Activity Log Manager (activity-log-manager)
For more details, see:
https://code.launchpad.net/~ev/activity-log-manager/whoopsie/+merge/93899
As discussed with Seif and the Canonical design team, we should merge the two existing privacy pages in GNOME Control Center into a single entity, under activity-log-manager. Here is a branch to do just that.
Christian has provided the following mockup as guidance:
http://dl.dropbox.com/u/2935618/canonical/ss/privacy-7.png
The privacy page for the Ubuntu crash report settings, hereafter referred to as "diagnostics," provides a small DBus daemon for writing the root-owned /etc/default/whoopsie preferences file.
This also adds a dependency on PolicyKit.
I've only made one change to activity-log-manager itself, which exposes a new append_page method to allow adding the diagnostics page.
As stated previously in #ubuntu-release and #ubuntu-devel, this code already exists in another form in the archive (whoopsie-daisy), and it is the release team's belief that it therefore falls under UI Freeze and not Feature Freeze. However, care will have to be taken to coordinate a release of whoopsie-daisy that does not have the aforementioned files.
--
https://code.launchpad.net/~ev/activity-log-manager/whoopsie/+merge/93899
Your team Activity Log Manager is requested to review the proposed merge of lp:~ev/activity-log-manager/whoopsie into lp:activity-log-manager.
=== modified file '.bzrignore'
--- .bzrignore 2012-02-15 19:55:47 +0000
+++ .bzrignore 2012-02-20 20:39:19 +0000
@@ -31,6 +31,7 @@
src/applications-widget.c
src/files-widget.c
src/history-widget.c
+src/diagnostics/Makefile
po/*.gmo
src/*.lo
po/stamp-it
=== modified file 'configure.ac'
--- configure.ac 2012-02-14 20:20:46 +0000
+++ configure.ac 2012-02-20 20:39:19 +0000
@@ -35,6 +35,7 @@
PKG_CHECK_MODULES(GTK, gtk+-3.0, [HAVE_GTK=yes], [HAVE_GTK=no])
PKG_CHECK_MODULES(GEE, gee-1.0, [HAVE_GEE=yes], [HAVE_GEE=no])
PKG_CHECK_MODULES(GIO_UNIX, gio-unix-2.0, [HAVE_GIO_UNIX=yes], [HAVE_GIO_UNIX=no])
+PKG_CHECK_MODULES(POLKIT, polkit-gobject-1, [HAVE_POLKIT=yes], [HAVE_POLKIT=no])
AC_ARG_WITH([extensiondir],
[AS_HELP_STRING([--with-extensiondir],
@@ -71,5 +72,6 @@
Makefile
data/Makefile
src/Makefile
+src/diagnostics/Makefile
po/Makefile.in
])
=== modified file 'po/POTFILES.in'
--- po/POTFILES.in 2012-02-14 20:20:46 +0000
+++ po/POTFILES.in 2012-02-20 20:39:19 +0000
@@ -6,3 +6,4 @@
src/applications-widget.vala
src/files-widget.vala
src/history-widget.vala
+src/diagnostics/whoopsie.ui
=== modified file 'src/Makefile.am'
--- src/Makefile.am 2012-02-08 14:19:18 +0000
+++ src/Makefile.am 2012-02-20 20:39:19 +0000
@@ -3,6 +3,8 @@
ccpanel_LTLIBRARIES = libactivity-log-manager.la
endif
+SUBDIRS = diagnostics
+
VALAFLAGS = \
--pkg zeitgeist-1.0 \
--pkg gtk+-3.0 \
@@ -13,6 +15,8 @@
bin_PROGRAMS = activity-log-manager
+gnomeccuidir = $(datadir)/gnome-control-center/ui/
+
SHARED_CFLAGS = \
-Wall \
-g \
@@ -21,14 +25,15 @@
-DPACKAGE_DATA_DIR=\""$(datadir)"\" \
-DPROGRAMNAME_LOCALEDIR=\"${PROGRAMNAME_LOCALEDIR}\" \
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \
+ -DGNOMECC_UI_DIR=\""$(gnomeccuidir)"\" \
$(GTK_CFLAGS) $(ZEITGEIST_CFLAGS) $(GEE_CFLAGS) $(GIO_UNIX_CFLAGS)
activity_log_manager_CFLAGS = \
$(SHARED_CFLAGS)
libactivity_log_manager_la_CFLAGS = \
$(SHARED_CFLAGS) \
+ $(POLKIT_CFLAGS) \
$(CCPANEL_CFLAGS)
-
SOURCES = \
activity-log-manager.vala \
history-widget.vala \
@@ -38,7 +43,9 @@
activity_log_manager_SOURCES = \
$(SOURCES) alm.vala
libactivity_log_manager_la_SOURCES = \
- $(SOURCES) alm-cc.c
+ $(SOURCES) alm-cc.c \
+ diagnostics-widget.c \
+ diagnostics/whoopsie-generated.c
activity_log_manager_LDFLAGS = \
-Wl,--export-dynamic
@@ -53,6 +60,7 @@
$(SHARED_LIBS)
libactivity_log_manager_la_LIBADD = \
$(SHARED_LIBS) \
+ $(POLKIT_LIBS) \
$(CCPANEL_LIBS)
GENERATED_C_FILES = $(alm_SOURCES:.vala=.c)
@@ -62,7 +70,3 @@
CLEANFILES = \
$(GENERATED_C_FILES) \
$(GENERATED_O_FILES)
-
-
-
-
=== modified file 'src/activity-log-manager.vala'
--- src/activity-log-manager.vala 2012-02-18 21:38:27 +0000
+++ src/activity-log-manager.vala 2012-02-20 20:39:19 +0000
@@ -71,6 +71,10 @@
this.show_all();
}
+ public void append_page (Gtk.Widget widget, string label) {
+ var app_label = new Gtk.Label(_(label));
+ notebook.append_page(widget, app_label);
+ }
public void on_incognito_toggled(bool status) {
this.logging_switch.set_active(!status);
}
=== modified file 'src/alm-cc.c'
--- src/alm-cc.c 2012-02-11 16:53:55 +0000
+++ src/alm-cc.c 2012-02-20 20:39:19 +0000
@@ -21,6 +21,8 @@
#include "config.h"
extern void* alm_activity_log_manager_new (void);
+extern void alm_activity_log_manager_append_page (void* alm, GtkWidget* widget, const gchar* label);
+extern void* whoopsie_daisy_preferences_new (void);
#define ALM_TYPE_MAIN_WINDOW_PANEL alm_main_window_panel_get_type()
@@ -53,6 +55,8 @@
alm_main_window_panel_init (AlmMainWindowPanel *self)
{
GtkWidget *widget = GTK_WIDGET (alm_activity_log_manager_new ());
+ GtkWidget *whoopsie = GTK_WIDGET (whoopsie_daisy_preferences_new ());
+ alm_activity_log_manager_append_page (widget, whoopsie, "Diagnostics");
gtk_widget_show_all (widget);
gtk_container_add (GTK_CONTAINER (self), widget);
}
=== added directory 'src/diagnostics'
=== added file 'src/diagnostics-widget.c'
--- src/diagnostics-widget.c 1970-01-01 00:00:00 +0000
+++ src/diagnostics-widget.c 2012-02-20 20:39:19 +0000
@@ -0,0 +1,195 @@
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+#include <libgnome-control-center/cc-panel.h>
+#include <polkit/polkit.h>
+
+#include "diagnostics/whoopsie-generated.h"
+
+static WhoopsiePreferences* proxy = NULL;
+
+#define POL_PATH "com.ubuntu.whoopsiepreferences.change"
+#define PRIVACY_URL "http://www.ubuntu.com/aboutus/privacypolicy"
+
+#define WHOOPSIE_DAISY_TYPE_PREFERENCES whoopsie_daisy_preferences_get_type()
+#define WHOOPSIE_DAISY_PREFERENCES(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ WHOOPSIE_DAISY_TYPE_PREFERENCES, WhoopsieDaisyPreferences))
+#define WHOOPSIE_DAISY_PREFERENCES_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), WHOOPSIE_DAISY_TYPE_PREFERENCES, WhoopsieDaisyPreferencesPrivate))
+
+GType whoopsie_daisy_preferences_get_type (void) G_GNUC_CONST;
+
+typedef struct _WhoopsieDaisyPreferences WhoopsieDaisyPreferences;
+typedef struct _WhoopsieDaisyPreferencesClass WhoopsieDaisyPreferencesClass;
+typedef struct _WhoopsieDaisyPreferencesPrivate WhoopsieDaisyPreferencesPrivate;
+
+struct _WhoopsieDaisyPreferencesPrivate
+{
+ GtkBuilder* builder;
+ GPermission* permission;
+};
+
+struct _WhoopsieDaisyPreferences
+{
+ GtkBox parent;
+ WhoopsieDaisyPreferencesPrivate* priv;
+};
+
+struct _WhoopsieDaisyPreferencesClass
+{
+ GtkBoxClass parent_class;
+};
+
+G_DEFINE_TYPE (WhoopsieDaisyPreferences, whoopsie_daisy_preferences, GTK_TYPE_BOX)
+
+static void
+whoopsie_daisy_preferences_dispose (GObject* object)
+{
+ WhoopsieDaisyPreferencesPrivate* priv = WHOOPSIE_DAISY_PREFERENCES (object)->priv;
+
+ if (priv->builder) {
+ g_object_unref (priv->builder);
+ priv->builder = NULL;
+ }
+ if (priv->permission) {
+ g_object_unref (priv->permission);
+ priv->permission = NULL;
+ }
+}
+
+static void
+whoopsie_daisy_preferences_class_init (WhoopsieDaisyPreferencesClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ g_type_class_add_private (klass, sizeof (WhoopsieDaisyPreferencesPrivate));
+ object_class->dispose = whoopsie_daisy_preferences_dispose;
+}
+
+static void
+on_privacy_policy_clicked (GtkWidget* button, gpointer user_data)
+{
+ system ("xdg-open " PRIVACY_URL);
+}
+
+static void
+on_permission_changed (GPermission* permission, GParamSpec* pspec, gpointer data)
+{
+ gboolean allowed;
+ GtkWidget* error_reports_box = NULL;
+ WhoopsieDaisyPreferencesPrivate* priv = WHOOPSIE_DAISY_PREFERENCES (data)->priv;
+
+ error_reports_box = GTK_WIDGET (gtk_builder_get_object (
+ priv->builder, "error_reports_box"));
+
+ allowed = g_permission_get_allowed (permission);
+ gtk_widget_set_sensitive (error_reports_box, allowed);
+}
+
+static void
+on_submit_error_reports_checked (GtkToggleButton* button, gpointer user_data)
+{
+ GError* error = NULL;
+
+ whoopsie_preferences_call_set_report_crashes_sync (proxy,
+ gtk_toggle_button_get_active (button), NULL, &error);
+ if (error != NULL) {
+ g_printerr ("Error setting crash reporting: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+on_properties_changed (WhoopsiePreferences* interface,
+ GVariant* changed_properties,
+ const gchar* const* invalidated_properties,
+ gpointer user_data)
+{
+ WhoopsieDaisyPreferencesPrivate* priv = WHOOPSIE_DAISY_PREFERENCES (user_data)->priv;
+ gboolean report_errors;
+ GtkWidget* submit_error_reports = NULL;
+
+ submit_error_reports = GTK_WIDGET (
+ gtk_builder_get_object (priv->builder, "submit_error_reports"));
+ report_errors = whoopsie_preferences_get_report_crashes (interface);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (submit_error_reports), report_errors);
+}
+
+static void
+whoopsie_daisy_preferences_setup_dbus (WhoopsieDaisyPreferences *self, GError *error)
+{
+ WhoopsieDaisyPreferencesPrivate* priv = WHOOPSIE_DAISY_PREFERENCES (self)->priv;
+ proxy = whoopsie_preferences_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ "com.ubuntu.WhoopsiePreferences",
+ "/com/ubuntu/WhoopsiePreferences",
+ NULL, &error);
+ if (!proxy)
+ return
+
+ g_signal_connect (proxy, "g-properties-changed",
+ G_CALLBACK (on_properties_changed), self);
+ on_properties_changed (proxy, NULL, NULL, self);
+}
+static void
+whoopsie_daisy_preferences_init (WhoopsieDaisyPreferences *self)
+{
+ GError *error = NULL;
+ GtkWidget* privacy_page = NULL;
+ GtkWidget* unlock_align = NULL;
+ GtkWidget* unlock_button = NULL;
+ GtkWidget* submit_error_reports = NULL;
+ GtkWidget* privacy_policy = NULL;
+ GtkBuilder* builder = NULL;
+ WhoopsieDaisyPreferencesPrivate* priv;
+ priv = self->priv = WHOOPSIE_DAISY_PREFERENCES_PRIVATE (self);
+
+ priv->builder = gtk_builder_new ();
+ gtk_builder_add_from_file(priv->builder, GNOMECC_UI_DIR "/whoopsie.ui", &error);
+ if (error != NULL) {
+ g_warning ("Could not load interface file: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ submit_error_reports = GTK_WIDGET (
+ gtk_builder_get_object (priv->builder, "submit_error_reports"));
+ privacy_page = GTK_WIDGET (
+ gtk_builder_get_object (priv->builder, "privacy_page_box"));
+ unlock_align = GTK_WIDGET (
+ gtk_builder_get_object (priv->builder, "unlock_alignment"));
+ privacy_policy = GTK_WIDGET (
+ gtk_builder_get_object (priv->builder, "privacy_policy"));
+
+ gtk_widget_reparent (privacy_page, (GtkWidget *) self);
+ g_object_set (self, "valign", GTK_ALIGN_START, NULL);
+
+ priv->permission = polkit_permission_new_sync (POL_PATH, NULL, NULL, &error);
+ if (!priv->permission) {
+ g_warning ("Could not acquire permission: %s", error->message);
+ g_error_free (error);
+ }
+
+ unlock_button = gtk_lock_button_new (priv->permission);
+ gtk_container_add (GTK_CONTAINER (unlock_align), GTK_WIDGET (unlock_button));
+ gtk_widget_show (unlock_button);
+
+ g_signal_connect (priv->permission, "notify", G_CALLBACK (on_permission_changed), self);
+ on_permission_changed (priv->permission, NULL, self);
+
+ whoopsie_daisy_preferences_setup_dbus (self, error);
+ if (error) {
+ g_warning ("Could not set up DBus connection: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_signal_connect (submit_error_reports, "toggled",
+ G_CALLBACK (on_submit_error_reports_checked), NULL);
+ g_signal_connect (privacy_policy, "clicked",
+ G_CALLBACK (on_privacy_policy_clicked), NULL);
+}
+
+GtkWidget*
+whoopsie_daisy_preferences_new (void)
+{
+ return g_object_new (WHOOPSIE_DAISY_TYPE_PREFERENCES, NULL);
+}
+
=== added file 'src/diagnostics/Makefile.am'
--- src/diagnostics/Makefile.am 1970-01-01 00:00:00 +0000
+++ src/diagnostics/Makefile.am 2012-02-20 20:39:19 +0000
@@ -0,0 +1,44 @@
+if HAVE_CCPANEL
+ccpaneldir = $(CCPANEL_DIR)
+bin_PROGRAMS = whoopsie-preferences
+endif
+
+policykitdir = $(datadir)/polkit-1/actions/
+dbussystemdir = $(sysconfdir)/dbus-1/system.d/
+dbusservicedir = $(datadir)/dbus-1/system-services/
+gnomeccuidir = $(datadir)/gnome-control-center/ui/
+
+whoopsie_preferences_CFLAGS = \
+ -Wall \
+ -g \
+ $(POLKIT_CFLAGS) $(GIO_UNIX_CFLAGS)
+
+whoopsie_preferences_SOURCES = \
+ whoopsie-generated.c whoopsie-generated.h whoopsie-preferences.c
+
+whoopsie_preferences_LDADD = \
+ $(POLKIT_LIBS) \
+ $(GIO_UNIX_LIBS)
+
+EXTRA_DIST = \
+ whoopsie-preferences.xml \
+ com.ubuntu.WhoopsiePreferences.service \
+ com.ubuntu.WhoopsiePreferences.conf \
+ com.ubuntu.whoopsiepreferences.policy \
+ whoopsie.ui
+
+gnomeccui_DATA = \
+ whoopsie.ui
+policykit_DATA = \
+ com.ubuntu.whoopsiepreferences.policy
+dbussystem_DATA = \
+ com.ubuntu.WhoopsiePreferences.conf
+dbusservice_DATA = \
+ com.ubuntu.WhoopsiePreferences.service
+
+whoopsie-generated.c: whoopsie-preferences.xml
+ gdbus-codegen --interface-prefix com.ubuntu. \
+ --generate-c-code whoopsie-generated \
+ $<
+
+CLEANFILES = whoopsie-generated.[ch]
=== added file 'src/diagnostics/com.ubuntu.WhoopsiePreferences.conf'
--- src/diagnostics/com.ubuntu.WhoopsiePreferences.conf 1970-01-01 00:00:00 +0000
+++ src/diagnostics/com.ubuntu.WhoopsiePreferences.conf 2012-02-20 20:39:19 +0000
@@ -0,0 +1,26 @@
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+ <!-- This configuration file specifies the required security policies
+ for configuring the crash daemon. -->
+
+ <!-- Only root can own the service -->
+ <policy user="root">
+ <allow own="com.ubuntu.WhoopsiePreferences"/>
+ </policy>
+
+ <!-- Allow anyone to invoke methods (further constrained by
+ PolicyKit privileges -->
+ <policy context="default">
+ <allow send_destination="com.ubuntu.WhoopsiePreferences"
+ send_interface="com.ubuntu.WhoopsiePreferences"/>
+ <allow send_destination="com.ubuntu.WhoopsiePreferences"
+ send_interface="org.freedesktop.DBus.Introspectable"/>
+ <allow send_destination="com.ubuntu.WhoopsiePreferences"
+ send_interface="org.freedesktop.DBus.Properties"/>
+ </policy>
+
+</busconfig>
+
=== added file 'src/diagnostics/com.ubuntu.WhoopsiePreferences.service'
--- src/diagnostics/com.ubuntu.WhoopsiePreferences.service 1970-01-01 00:00:00 +0000
+++ src/diagnostics/com.ubuntu.WhoopsiePreferences.service 2012-02-20 20:39:19 +0000
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=com.ubuntu.WhoopsiePreferences
+Exec=/usr/lib/whoopsie/whoopsie-preferences
+User=root
=== added file 'src/diagnostics/com.ubuntu.whoopsiepreferences.policy'
--- src/diagnostics/com.ubuntu.whoopsiepreferences.policy 1970-01-01 00:00:00 +0000
+++ src/diagnostics/com.ubuntu.whoopsiepreferences.policy 2012-02-20 20:39:19 +0000
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
+<policyconfig>
+ <vendor>Ubuntu crash reporting</vendor>
+ <vendor_url>https://launchpad.net/whoopsie-daisy</vendor_url>
+ <icon_name>stock_lock</icon_name>
+ <action id="com.ubuntu.whoopsiepreferences.change">
+ <description gettext-domain="whoopsie">Privacy settings</description>
+ <message gettext-domain="whoopsie">To change your privacy settings you need to authenticate.</message>
+ <defaults>
+ <allow_any>auth_admin</allow_any>
+ <allow_inactive>auth_admin</allow_inactive>
+ <allow_active>auth_admin_keep</allow_active>
+ </defaults>
+ </action>
+</policyconfig>
=== added file 'src/diagnostics/whoopsie-preferences.c'
--- src/diagnostics/whoopsie-preferences.c 1970-01-01 00:00:00 +0000
+++ src/diagnostics/whoopsie-preferences.c 2012-02-20 20:39:19 +0000
@@ -0,0 +1,297 @@
+/* whoopsie
+ *
+ * Copyright © 2011 Canonical Ltd.
+ * Author: Evan Dandrea <evan.dandrea@xxxxxxxxxxxxx>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gio/gio.h>
+#include <stdlib.h>
+#include <polkit/polkit.h>
+
+#include "whoopsie-generated.h"
+
+#define CONFIG_PATH "/etc/default/whoopsie"
+
+static GMainLoop* loop = NULL;
+static guint loop_shutdown = 0;
+static GKeyFile* key_file = NULL;
+static PolkitAuthority* authority = NULL;
+
+/* Eventually, it might make sense to move to gsettings with the dconf
+ * backend, once it gains PolicyKit support, rather than have a program just
+ * to expose an interface to a small configuration file over DBus/PolicyKit.
+ * */
+
+/* Once upstart has an interface for disabiling jobs via initctl, we wont need
+ * a configuration file anymore */
+
+gboolean
+whoopsie_preferences_load_configuration (void)
+{
+ char* data;
+ gsize data_size;
+ gboolean ret = TRUE;
+ GError* error = NULL;
+
+ if (g_key_file_load_from_file (key_file, CONFIG_PATH,
+ G_KEY_FILE_KEEP_COMMENTS, NULL)) {
+ return TRUE;
+ }
+
+ g_key_file_set_boolean (key_file, "General", "report_crashes", TRUE);
+ data = g_key_file_to_data (key_file, &data_size, &error);
+ if (error) {
+ g_print ("Could not process configuration: %s\n", error->message);
+ ret = FALSE;
+ goto out;
+ }
+ if (!g_file_set_contents (CONFIG_PATH, data, data_size, &error)) {
+ g_print ("Could not write configuration: %s\n", error->message);
+ ret = FALSE;
+ goto out;
+ }
+
+ out:
+ if (data)
+ g_free (data);
+ if (error)
+ g_error_free (error);
+ return ret;
+}
+
+static void
+whoopsie_preferences_dbus_notify (WhoopsiePreferences* interface)
+{
+ GError* error = NULL;
+ gboolean report_crashes = FALSE;
+
+ report_crashes = g_key_file_get_boolean (key_file, "General",
+ "report_crashes", &error);
+ if (error) {
+ g_warning ("Could not get crashes: %s", error->message);
+ g_error_free (error);
+ }
+ whoopsie_preferences_set_report_crashes (interface, report_crashes);
+}
+
+static void
+whoopsie_preferences_file_changed (GFileMonitor *monitor, GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ if (event_type == G_FILE_MONITOR_EVENT_CHANGED) {
+ whoopsie_preferences_load_configuration ();
+ whoopsie_preferences_dbus_notify (user_data);
+ }
+}
+
+gboolean
+whoopsie_preferences_load (WhoopsiePreferences* interface)
+{
+ GError* error = NULL;
+ GFile* fp = NULL;
+ GFileMonitor* file_monitor = NULL;
+
+ fp = g_file_new_for_path (CONFIG_PATH);
+ file_monitor = g_file_monitor_file (fp, G_FILE_MONITOR_NONE,
+ NULL, &error);
+ g_signal_connect (file_monitor, "changed",
+ G_CALLBACK (whoopsie_preferences_file_changed),
+ interface);
+ if (error) {
+ g_print ("Could not set up file monitor: %s\n", error->message);
+ g_error_free (error);
+ }
+ g_object_unref (fp);
+
+ key_file = g_key_file_new ();
+ whoopsie_preferences_load_configuration ();
+}
+
+gboolean
+whoopsie_preferences_changed (WhoopsiePreferences* object, GParamSpec* pspec,
+ gpointer user_data)
+{
+ WhoopsiePreferencesIface* iface;
+ gboolean saved_value, new_value;
+ GError* error = NULL;
+ char* data;
+ gsize data_size;
+
+ if (loop_shutdown) {
+ g_source_remove (loop_shutdown);
+ loop_shutdown = 0;
+ }
+ loop_shutdown = g_timeout_add_seconds (60, (GSourceFunc) g_main_loop_quit,
+ loop);
+
+ iface = WHOOPSIE_PREFERENCES_GET_IFACE (object);
+ saved_value = g_key_file_get_boolean (key_file, "General", user_data,
+ &error);
+ if (error) {
+ g_print ("Could not process configuration: %s\n", error->message);
+ return FALSE;
+ }
+ new_value = iface->get_report_crashes (object);
+
+ if (saved_value != new_value) {
+ g_key_file_set_boolean (key_file, "General", user_data, new_value);
+ data = g_key_file_to_data (key_file, &data_size, &error);
+ if (error) {
+ g_print ("Could not process configuration: %s\n", error->message);
+ return FALSE;
+ }
+ if (!g_file_set_contents (CONFIG_PATH, data, data_size, &error)) {
+ g_print ("Could not write configuration: %s\n", error->message);
+ return FALSE;
+ }
+ }
+}
+
+static gboolean
+whoopsie_preferences_on_set_report_crashes (WhoopsiePreferences* object,
+ GDBusMethodInvocation* invocation,
+ gboolean report,
+ gpointer user_data)
+{
+ whoopsie_preferences_set_report_crashes (object, report);
+ whoopsie_preferences_complete_set_report_crashes (object, invocation);
+ return TRUE;
+}
+
+static gboolean
+whoopsie_preferences_authorize_method (GDBusInterfaceSkeleton* interface,
+ GDBusMethodInvocation* invocation,
+ gpointer user_data)
+{
+ PolkitSubject* subject = NULL;
+ PolkitAuthorizationResult* result = NULL;
+ GError* error = NULL;
+ const char* sender = NULL;
+ gboolean ret = FALSE;
+
+ sender = g_dbus_method_invocation_get_sender (invocation);
+ subject = polkit_system_bus_name_new (sender);
+ result = polkit_authority_check_authorization_sync (authority, subject,
+ "com.ubuntu.whoopsiepreferences.change",
+ NULL,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
+ NULL, &error);
+ if (result == NULL) {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_AUTH_FAILED, "Could not authorize: %s",
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ if (!polkit_authorization_result_get_is_authorized (result)) {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_AUTH_FAILED, "Not authorized.");
+ goto out;
+ }
+ ret = TRUE;
+ out:
+ if (result != NULL)
+ g_object_unref (result);
+ g_object_unref (subject);
+ return ret;
+}
+
+static void
+on_bus_acquired (GDBusConnection* connection, const gchar* name,
+ gpointer user_data)
+{
+ WhoopsiePreferences* interface;
+ GError* error = NULL;
+
+ interface = whoopsie_preferences_skeleton_new ();
+ if (!g_dbus_interface_skeleton_export (
+ G_DBUS_INTERFACE_SKELETON (interface),
+ connection,
+ "/com/ubuntu/WhoopsiePreferences", &error)) {
+
+ g_print ("Could not export path: %s\n", error->message);
+ g_error_free (error);
+ g_main_loop_quit (loop);
+ return;
+ }
+
+ authority = polkit_authority_get_sync (NULL, &error);
+ if (authority == NULL) {
+ g_print ("Could not get authority: %s\n", error->message);
+ g_error_free (error);
+ g_main_loop_quit (loop);
+ return;
+ }
+ loop_shutdown = g_timeout_add_seconds (60, (GSourceFunc) g_main_loop_quit,
+ loop);
+
+ g_signal_connect (interface, "notify::report-crashes",
+ G_CALLBACK (whoopsie_preferences_changed),
+ "report_crashes");
+ g_signal_connect (interface, "handle-set-report-crashes",
+ G_CALLBACK (whoopsie_preferences_on_set_report_crashes),
+ NULL);
+ g_signal_connect (interface, "g-authorize-method", G_CALLBACK
+ (whoopsie_preferences_authorize_method), authority);
+
+ whoopsie_preferences_load (interface);
+ whoopsie_preferences_dbus_notify (interface);
+}
+
+static void
+on_name_acquired (GDBusConnection* connection, const gchar* name,
+ gpointer user_data)
+{
+ g_print ("Acquired the name: %s\n", name);
+}
+
+static void
+on_name_lost (GDBusConnection* connection, const gchar* name,
+ gpointer user_data)
+{
+ g_print ("Lost the name: %s\n", name);
+}
+
+int
+main (int argc, char** argv)
+{
+ guint owner_id;
+
+ if (getuid () != 0) {
+ g_print ("This program must be run as root.\n");
+ return 1;
+ }
+
+ g_type_init();
+
+ owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
+ "com.ubuntu.WhoopsiePreferences",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus_acquired,
+ on_name_acquired,
+ on_name_lost,
+ NULL, NULL);
+
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+ g_bus_unown_name (owner_id);
+ g_main_loop_unref (loop);
+ if (key_file)
+ g_key_file_free (key_file);
+ return 0;
+}
=== added file 'src/diagnostics/whoopsie-preferences.xml'
--- src/diagnostics/whoopsie-preferences.xml 1970-01-01 00:00:00 +0000
+++ src/diagnostics/whoopsie-preferences.xml 2012-02-20 20:39:19 +0000
@@ -0,0 +1,8 @@
+<node>
+ <interface name="com.ubuntu.WhoopsiePreferences">
+ <property name="ReportCrashes" type="b" access="read" />
+ <method name="SetReportCrashes">
+ <arg direction="in" type="b" name="report" />
+ </method>
+ </interface>
+</node>
=== added file 'src/diagnostics/whoopsie.ui'
--- src/diagnostics/whoopsie.ui 1970-01-01 00:00:00 +0000
+++ src/diagnostics/whoopsie.ui 2012-02-20 20:39:19 +0000
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <object class="GtkWindow" id="window1">
+ <property name="can_focus">False</property>
+ <property name="has_resize_grip">False</property>
+ <child>
+ <object class="GtkBox" id="privacy_page_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="privacy_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="privacy_heading">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Ubuntu can collect anonymous information that helps developers improve it. All information collected is covered by our privacy policy.</property>
+ <property name="wrap">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="privacy_policy_alignment">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="xscale">0</property>
+ <child>
+ <object class="GtkButton" id="privacy_policy">
+ <property name="label" translatable="yes">Privacy Policy</property>
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="reports_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox" id="reports_heading_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkLabel" id="reports_heading">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">People using this computer can:</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="unlock_alignment">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">1</property>
+ <property name="xscale">0</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="error_reports_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkCheckButton" id="submit_error_reports">
+ <property name="label" translatable="yes">Send error reports to Canonical</property>
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="error_reports_description">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="xalign">0</property>
+ <property name="xpad">24</property>
+ <property name="label" translatable="yes"><small>Error reports include information about what a program was doing when it failed. You always have the choice to send or cancel an error report.</small></property>
+ <property name="use_markup">True</property>
+ <property name="wrap">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
Follow ups