Khurshid Alam has proposed merging 
lp:~khurshid-alam/unity-settings-daemon/sharing-plugin into 
lp:unity-settings-daemon.

Commit message:
Add sharing plugin

we are importing sharing panel from gnome-control-center as the old 
screen-sharing panel does not work anymore due to a gsettings key removal from 
vino. Our new sharing panel will use this plugin. This plugin is a direct port 
from gnome-settings-daemon 3.22.

Requested reviews:
  Marco Trevisan (Treviño) (3v1n0)
Related bugs:
  Bug #1741027 in unity-control-center (Ubuntu): "[FFE] Screen sharing panels 
abort using an non-existent vino gsettings key"
  https://bugs.launchpad.net/ubuntu/+source/unity-control-center/+bug/1741027

For more details, see:
https://code.launchpad.net/~khurshid-alam/unity-settings-daemon/sharing-plugin/+merge/355887

PPA: unity7maintainers/unity7-desktop

Testing: 
https://community.ubuntu.com/t/testing-of-sharing-panel-in-u-c-c-bionic/4215

The related control center branch is 
https://code.launchpad.net/~khurshid-alam/unity-control-center/sharing-panel
-- 
Your team Unity Settings Daemon Development Team is subscribed to branch 
lp:unity-settings-daemon.
=== modified file 'configure.ac'
--- configure.ac	2017-03-24 03:49:07 +0000
+++ configure.ac	2018-09-30 12:23:49 +0000
@@ -58,6 +58,7 @@
 GSETTINGS_DESKTOP_SCHEMAS_REQUIRED_VERSION=3.7.2.1
 XRANDR_REQUIRED_VERSION=1.3
 XEXT_REQUIRED_VERSION=1.1
+NM_REQUIRED_VERSION=1.0
 
 EXTRA_COMPILE_WARNINGS(yes)
 
@@ -376,6 +377,24 @@
 
 AC_SUBST(NSS_DATABASE)
 
+dnl ---------------------------------------------------------------------------
+dnl Sharing plugin
+dnl ---------------------------------------------------------------------------
+
+AC_ARG_ENABLE(network-manager,
+        AS_HELP_STRING([--disable-network-manager],
+                       [Disable NetworkManager support]),
+        enable_network_manager=$enableval,
+        enable_network_manager=yes)
+
+if test "x$enable_network_manager" = "xyes" ; then
+        NM_MODULE="libnm >= $NM_REQUIRED_VERSION"
+        AC_DEFINE(HAVE_NETWORK_MANAGER, 1, [Defined if NetworkManager support is enabled])
+else
+        NM_MODULE=
+fi
+
+PKG_CHECK_MODULES(SHARING, gio-2.0 $NM_MODULE)
 
 # ---------------------------------------------------------------------------
 # Enable Profiling
@@ -497,6 +516,7 @@
 plugins/orientation/Makefile
 plugins/remote-display/Makefile
 plugins/screensaver-proxy/Makefile
+plugins/sharing/Makefile
 plugins/smartcard/Makefile
 plugins/sound/Makefile
 plugins/updates/Makefile
@@ -537,6 +557,7 @@
 
         Session tracking:         ${SESSION_TRACKING}
         LCMS DICT support:        ${have_new_lcms}
+        NetworkManager support:   ${enable_network_manager}
         IBus support:             ${enable_ibus}
         Fcitx support:            ${enable_fcitx}
         Libnotify support:        ${have_libnotify}

=== modified file 'debian/control'
--- debian/control	2018-04-13 18:45:04 +0000
+++ debian/control	2018-09-30 12:23:49 +0000
@@ -13,6 +13,7 @@
                libdbus-glib-1-dev (>= 0.74),
                libglib2.0-dev (>= 2.35.3),
                libgtk-3-dev (>= 3.7.8),
+               libnm-dev (>= 1.0) [linux-any],
                libnotify-dev (>= 0.7.0),
                libxt-dev,
                libxi-dev,

=== modified file 'debian/rules'
--- debian/rules	2018-04-13 18:45:04 +0000
+++ debian/rules	2018-09-30 12:23:49 +0000
@@ -8,7 +8,7 @@
 
 DEB_DH_MAKESHLIBS_ARGS_ALL += -X/usr/lib/unity-settings-daemon-1.0
 DEB_CONFIGURE_SCRIPT := ./autogen.sh
-DEB_CONFIGURE_EXTRA_FLAGS = --disable-packagekit --enable-ibus --enable-fcitx
+DEB_CONFIGURE_EXTRA_FLAGS = --disable-packagekit --enable-ibus --enable-fcitx --enable-network-manager
 
 build/unity-settings-daemon::
 	gcc -o gnome-settings-daemon/gnome-update-wallpaper-cache debian/gnome-update-wallpaper-cache.c `pkg-config --cflags --libs glib-2.0 gdk-3.0 gdk-x11-3.0 gio-2.0 gnome-desktop-3.0`

=== modified file 'plugins/Makefile.am'
--- plugins/Makefile.am	2017-03-24 03:49:07 +0000
+++ plugins/Makefile.am	2018-09-30 12:23:49 +0000
@@ -16,6 +16,7 @@
 	mouse		\
 	remote-display	\
 	screensaver-proxy \
+	sharing     \
 	sound		\
 	xrandr		\
 	xsettings	\

=== added directory 'plugins/sharing'
=== added file 'plugins/sharing/Makefile.am'
--- plugins/sharing/Makefile.am	1970-01-01 00:00:00 +0000
+++ plugins/sharing/Makefile.am	2018-09-30 12:23:49 +0000
@@ -0,0 +1,49 @@
+plugin_name = sharing
+
+plugin_LTLIBRARIES = libsharing.la
+
+libsharing_la_SOURCES =		\
+	gsd-sharing-manager.c	\
+	gsd-sharing-manager.h	\
+	gsd-sharing-enums.h	\
+	gsd-sharing-plugin.c
+
+libsharing_la_CPPFLAGS =					\
+	-I$(top_srcdir)/gnome-settings-daemon			\
+	-I$(top_builddir)/gnome-settings-daemon			\
+	-DGNOME_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\"	\
+	$(AM_CPPFLAGS)
+
+libsharing_la_CFLAGS =			\
+	-I$(top_srcdir)/plugins/common	\
+	$(SHARING_CFLAGS)		\
+	$(PLUGIN_CFLAGS)		\
+	$(SETTINGS_PLUGIN_CFLAGS)	\
+	$(AM_CFLAGS)
+
+libsharing_la_LDFLAGS = $(GSD_PLUGIN_LDFLAGS)
+
+libsharing_la_LIBADD  = $(SETTINGS_PLUGIN_LIBS) $(SHARING_LIBS)
+
+noinst_PROGRAMS = gsd-test-sharing
+gsd_test_sharing_SOURCES =				\
+	gsd-sharing-manager.c				\
+	gsd-sharing-manager.h				\
+	test-sharing.c
+
+gsd_test_sharing_CFLAGS = $(libsharing_la_CFLAGS)
+gsd_test_sharing_CPPFLAGS = $(libsharing_la_CPPFLAGS)
+gsd_test_sharing_LDADD =				\
+	$(top_builddir)/gnome-settings-daemon/libgsd.la \
+	$(SHARING_LIBS)					\
+	$(SETTINGS_PLUGIN_LIBS)
+
+plugin_in_files = sharing.gnome-settings-plugin.in
+
+plugin_DATA = $(plugin_in_files:.gnome-settings-plugin.in=.gnome-settings-plugin)
+
+EXTRA_DIST = $(plugin_in_files)
+CLEANFILES = $(plugin_DATA)
+DISTCLEANFILES = $(plugin_DATA)
+
+@GSD_INTLTOOL_PLUGIN_RULE@

=== added file 'plugins/sharing/gsd-sharing-enums.h'
--- plugins/sharing/gsd-sharing-enums.h	1970-01-01 00:00:00 +0000
+++ plugins/sharing/gsd-sharing-enums.h	2018-09-30 12:23:49 +0000
@@ -0,0 +1,34 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2014 Bastien Nocera <[email protected]>
+ *
+ * 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 2 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/>.
+ *
+ */
+
+#ifndef __GSD_SHARING_ENUMS_H
+#define __GSD_SHARING_ENUMS_H
+
+G_BEGIN_DECLS
+
+typedef enum {
+       GSD_SHARING_STATUS_OFFLINE,
+       GSD_SHARING_STATUS_DISABLED_MOBILE_BROADBAND,
+       GSD_SHARING_STATUS_DISABLED_LOW_SECURITY,
+       GSD_SHARING_STATUS_AVAILABLE
+} GsdSharingStatus;
+
+G_END_DECLS
+
+#endif /* __GSD_SHARING_ENUMS_H */

=== added file 'plugins/sharing/gsd-sharing-manager.c'
--- plugins/sharing/gsd-sharing-manager.c	1970-01-01 00:00:00 +0000
+++ plugins/sharing/gsd-sharing-manager.c	2018-09-30 12:23:49 +0000
@@ -0,0 +1,822 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2014 Bastien Nocera <[email protected]>
+ *
+ * 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 2 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 "config.h"
+
+#include <locale.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <gio/gdesktopappinfo.h>
+#include <glib/gstdio.h>
+
+#ifdef HAVE_NETWORK_MANAGER
+#include <NetworkManager.h>
+#endif /* HAVE_NETWORK_MANAGER */
+
+#include "gnome-settings-plugin.h"
+#include "gnome-settings-profile.h"
+#include "gsd-sharing-manager.h"
+#include "gsd-sharing-enums.h"
+
+#define GSD_SHARING_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SHARING_MANAGER, GsdSharingManagerPrivate))
+
+typedef struct {
+        const char  *name;
+        GSettings   *settings;
+        gboolean     started;
+        GSubprocess *process;
+} ServiceInfo;
+
+struct GsdSharingManagerPrivate
+{
+        GDBusNodeInfo           *introspection_data;
+        guint                    name_id;
+        GDBusConnection         *connection;
+
+        GCancellable            *cancellable;
+#ifdef HAVE_NETWORK_MANAGER
+        NMClient                *client;
+#endif /* HAVE_NETWORK_MANAGER */
+
+        GHashTable              *services;
+
+        char                    *current_network;
+        char                    *current_network_name;
+        char                    *carrier_type;
+        GsdSharingStatus         sharing_status;
+};
+
+#define GSD_SHARING_DBUS_NAME GSD_DBUS_NAME ".Sharing"
+#define GSD_SHARING_DBUS_PATH GSD_DBUS_PATH "/Sharing"
+
+static const gchar introspection_xml[] =
+"<node>"
+"  <interface name='org.gnome.SettingsDaemon.Sharing'>"
+"    <annotation name='org.freedesktop.DBus.GLib.CSymbol' value='gsd_sharing_manager'/>"
+"    <property name='CurrentNetwork' type='s' access='read'/>"
+"    <property name='CurrentNetworkName' type='s' access='read'/>"
+"    <property name='CarrierType' type='s' access='read'/>"
+"    <property name='SharingStatus' type='u' access='read'/>"
+"    <method name='EnableService'>"
+"      <arg name='service-name' direction='in' type='s'/>"
+"    </method>"
+"    <method name='DisableService'>"
+"      <arg name='service-name' direction='in' type='s'/>"
+"      <arg name='network' direction='in' type='s'/>"
+"    </method>"
+"    <method name='ListNetworks'>"
+"      <arg name='service-name' direction='in' type='s'/>"
+"      <arg name='networks' direction='out' type='a(sss)'/>"
+"    </method>"
+"  </interface>"
+"</node>";
+
+static void     gsd_sharing_manager_class_init  (GsdSharingManagerClass *klass);
+static void     gsd_sharing_manager_init        (GsdSharingManager      *manager);
+static void     gsd_sharing_manager_finalize    (GObject                *object);
+
+G_DEFINE_TYPE (GsdSharingManager, gsd_sharing_manager, G_TYPE_OBJECT)
+
+static gpointer manager_object = NULL;
+
+static const char * const services[] = {
+        "rygel",
+        "vino-server",
+        "gnome-user-share-webdav"
+};
+
+static void
+gsd_sharing_manager_start_service (GsdSharingManager *manager,
+                                   ServiceInfo       *service)
+{
+        GDesktopAppInfo *app;
+        const char *exec;
+        char *desktop, **argvp;
+        GError *error = NULL;
+
+        if (service->started)
+                return;
+        g_debug ("About to start %s", service->name);
+
+        desktop = g_strdup_printf ("%s.desktop", service->name);
+        app = g_desktop_app_info_new (desktop);
+        g_free (desktop);
+
+        if (!app) {
+                g_warning ("Could not find desktop file for service '%s'", service->name);
+                return;
+        }
+
+        exec = g_app_info_get_commandline (G_APP_INFO (app));
+
+        if (!g_shell_parse_argv (exec, NULL, &argvp, &error)) {
+                g_warning ("Could not parse command-line '%s': %s", exec, error->message);
+                g_error_free (error);
+                g_object_unref (app);
+                return;
+        }
+
+        service->process = g_subprocess_newv ((const gchar * const*) argvp, G_SUBPROCESS_FLAGS_NONE, &error);
+
+        if (!service->process) {
+                g_warning ("Could not start command-line '%s': %s", exec, error->message);
+                g_error_free (error);
+                service->started = FALSE;
+        } else {
+                service->started = TRUE;
+        }
+
+        g_strfreev (argvp);
+        g_object_unref (app);
+}
+
+#ifdef HAVE_NETWORK_MANAGER
+static gboolean
+service_is_enabled_on_current_connection (GsdSharingManager *manager,
+                                          ServiceInfo       *service)
+{
+        char **connections;
+        int j;
+        gboolean ret;
+        connections = g_settings_get_strv (service->settings, "enabled-connections");
+        ret = FALSE;
+        for (j = 0; connections[j] != NULL; j++) {
+                if (g_strcmp0 (connections[j], manager->priv->current_network) == 0) {
+                        ret = TRUE;
+                        break;
+                }
+        }
+
+        g_strfreev (connections);
+        return ret;
+}
+#else
+static gboolean
+service_is_enabled_on_current_connection (GsdSharingManager *manager,
+                                          ServiceInfo       *service)
+{
+        return FALSE;
+}
+#endif /* HAVE_NETWORK_MANAGER */
+
+static void
+gsd_sharing_manager_stop_service (GsdSharingManager *manager,
+                                  ServiceInfo       *service)
+{
+        if (!service->started ||
+            service->process == NULL) {
+                    return;
+        }
+
+        g_debug ("About to stop %s", service->name);
+
+        g_subprocess_send_signal (service->process, SIGTERM);
+        g_clear_object (&service->process);
+        service->started = FALSE;
+}
+
+static void
+gsd_sharing_manager_sync_services (GsdSharingManager *manager)
+{
+        GList *services, *l;
+
+        services = g_hash_table_get_values (manager->priv->services);
+
+        for (l = services; l != NULL; l = l->next) {
+                ServiceInfo *service = l->data;
+                gboolean should_be_started = FALSE;
+
+                if (manager->priv->sharing_status == GSD_SHARING_STATUS_AVAILABLE &&
+                    service_is_enabled_on_current_connection (manager, service))
+                        should_be_started = TRUE;
+
+                if (service->started != should_be_started) {
+                        if (service->started)
+                                gsd_sharing_manager_stop_service (manager, service);
+                        else
+                                gsd_sharing_manager_start_service (manager, service);
+                }
+        }
+        g_list_free (services);
+}
+
+#ifdef HAVE_NETWORK_MANAGER
+static void
+properties_changed (GsdSharingManager *manager)
+{
+        GVariantBuilder props_builder;
+        GVariant *props_changed = NULL;
+
+        /* not yet connected to the session bus */
+        if (manager->priv->connection == NULL)
+                return;
+
+        g_variant_builder_init (&props_builder, G_VARIANT_TYPE ("a{sv}"));
+
+        g_variant_builder_add (&props_builder, "{sv}", "CurrentNetwork",
+                               g_variant_new_string (manager->priv->current_network));
+        g_variant_builder_add (&props_builder, "{sv}", "CurrentNetworkName",
+                               g_variant_new_string (manager->priv->current_network_name));
+        g_variant_builder_add (&props_builder, "{sv}", "CarrierType",
+                               g_variant_new_string (manager->priv->carrier_type));
+        g_variant_builder_add (&props_builder, "{sv}", "SharingStatus",
+                               g_variant_new_uint32 (manager->priv->sharing_status));
+
+        props_changed = g_variant_new ("(s@a{sv}@as)", GSD_SHARING_DBUS_NAME,
+                                       g_variant_builder_end (&props_builder),
+                                       g_variant_new_strv (NULL, 0));
+
+        g_dbus_connection_emit_signal (manager->priv->connection,
+                                       NULL,
+                                       GSD_SHARING_DBUS_PATH,
+                                       "org.freedesktop.DBus.Properties",
+                                       "PropertiesChanged",
+                                       props_changed, NULL);
+}
+
+static char **
+get_connections_for_service (GsdSharingManager *manager,
+                             const char        *service_name)
+{
+        ServiceInfo *service;
+
+        service = g_hash_table_lookup (manager->priv->services, service_name);
+        return g_settings_get_strv (service->settings, "enabled-connections");
+}
+#else
+static char **
+get_connections_for_service (GsdSharingManager *manager,
+                             const char        *service_name)
+{
+        const char * const * connections [] = { NULL };
+        return g_strdupv ((char **) connections);
+}
+#endif /* HAVE_NETWORK_MANAGER */
+
+static gboolean
+check_service (GsdSharingManager  *manager,
+               const char         *service_name,
+               GError            **error)
+{
+        if (g_hash_table_lookup (manager->priv->services, service_name))
+                return TRUE;
+
+        g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
+                     "Invalid service name '%s'", service_name);
+        return FALSE;
+}
+
+static gboolean
+gsd_sharing_manager_enable_service (GsdSharingManager  *manager,
+                                    const char         *service_name,
+                                    GError            **error)
+{
+        ServiceInfo *service;
+        char **connections;
+        GPtrArray *array;
+        guint i;
+
+        if (!check_service (manager, service_name, error))
+                return FALSE;
+
+        if (manager->priv->sharing_status != GSD_SHARING_STATUS_AVAILABLE) {
+                g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
+                             "Sharing cannot be enabled on this network, status is '%d'", manager->priv->sharing_status);
+                return FALSE;
+        }
+
+        service = g_hash_table_lookup (manager->priv->services, service_name);
+        connections = g_settings_get_strv (service->settings, "enabled-connections");
+        array = g_ptr_array_new ();
+        for (i = 0; connections[i] != NULL; i++) {
+                if (g_strcmp0 (connections[i], manager->priv->current_network) == 0)
+                        goto bail;
+                g_ptr_array_add (array, connections[i]);
+        }
+        g_ptr_array_add (array, manager->priv->current_network);
+        g_ptr_array_add (array, NULL);
+
+        g_settings_set_strv (service->settings, "enabled-connections", (const gchar *const *) array->pdata);
+
+bail:
+
+        gsd_sharing_manager_start_service (manager, service);
+
+        g_ptr_array_unref (array);
+        g_strfreev (connections);
+
+        return TRUE;
+}
+
+static gboolean
+gsd_sharing_manager_disable_service (GsdSharingManager  *manager,
+                                     const char         *service_name,
+                                     const char         *network_name,
+                                     GError            **error)
+{
+        ServiceInfo *service;
+        char **connections;
+        GPtrArray *array;
+        guint i;
+
+        if (!check_service (manager, service_name, error))
+                return FALSE;
+
+        service = g_hash_table_lookup (manager->priv->services, service_name);
+        connections = g_settings_get_strv (service->settings, "enabled-connections");
+        array = g_ptr_array_new ();
+        for (i = 0; connections[i] != NULL; i++) {
+                if (g_strcmp0 (connections[i], network_name) != 0)
+                        g_ptr_array_add (array, connections[i]);
+        }
+        g_ptr_array_add (array, NULL);
+
+        g_settings_set_strv (service->settings, "enabled-connections", (const gchar *const *) array->pdata);
+        g_ptr_array_unref (array);
+        g_strfreev (connections);
+
+        if (g_str_equal (network_name, manager->priv->current_network))
+                gsd_sharing_manager_stop_service (manager, service);
+
+        return TRUE;
+}
+
+#ifdef HAVE_NETWORK_MANAGER
+static const char *
+get_type_and_name_for_connection_uuid (GsdSharingManager *manager,
+                                       const char        *uuid,
+                                       const char       **name)
+{
+        NMRemoteConnection *conn;
+        const char *type;
+
+        if (!manager->priv->client)
+                return NULL;
+
+        conn = nm_client_get_connection_by_uuid (manager->priv->client, uuid);
+        if (!conn)
+                return NULL;
+        type = nm_connection_get_connection_type (NM_CONNECTION (conn));
+        *name = nm_connection_get_id (NM_CONNECTION (conn));
+
+        return type;
+}
+#else
+static const char *
+get_type_and_name_for_connection_uuid (GsdSharingManager *manager,
+                                       const char        *id,
+                                       const char       **name)
+{
+        return NULL;
+}
+#endif /* HAVE_NETWORK_MANAGER */
+
+#ifdef HAVE_NETWORK_MANAGER
+static gboolean
+connection_is_low_security (GsdSharingManager *manager,
+                            const char        *uuid)
+{
+        NMRemoteConnection *conn;
+
+        if (!manager->priv->client)
+                return TRUE;
+
+        conn = nm_client_get_connection_by_uuid (manager->priv->client, uuid);
+        if (!conn)
+                return TRUE;
+
+        /* Disable sharing on open Wi-Fi
+         * XXX: Also do this for WEP networks? */
+        return (nm_connection_get_setting_wireless_security (NM_CONNECTION (conn)) == NULL);
+}
+#endif /* HAVE_NETWORK_MANAGER */
+
+static GVariant *
+gsd_sharing_manager_list_networks (GsdSharingManager  *manager,
+                                   const char         *service_name,
+                                   GError            **error)
+{
+        char **connections;
+        GVariantBuilder builder;
+        guint i;
+
+        if (!check_service (manager, service_name, error))
+                return NULL;
+
+#ifdef HAVE_NETWORK_MANAGER
+        if (!manager->priv->client) {
+                g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Not ready yet");
+                return NULL;
+        }
+#endif /* HAVE_NETWORK_MANAGER */
+
+        connections = get_connections_for_service (manager, service_name);
+
+        g_variant_builder_init (&builder, G_VARIANT_TYPE ("(a(sss))"));
+        g_variant_builder_open (&builder, G_VARIANT_TYPE ("a(sss)"));
+
+        for (i = 0; connections[i] != NULL; i++) {
+                const char *type, *name;
+
+                type = get_type_and_name_for_connection_uuid (manager, connections[i], &name);
+                if (!type)
+                        continue;
+
+                g_variant_builder_add (&builder, "(sss)", connections[i], name, type);
+        }
+        g_strfreev (connections);
+
+        g_variant_builder_close (&builder);
+
+        return g_variant_builder_end (&builder);
+}
+
+static GVariant *
+handle_get_property (GDBusConnection *connection,
+                     const gchar     *sender,
+                     const gchar     *object_path,
+                     const gchar     *interface_name,
+                     const gchar     *property_name,
+                     GError         **error,
+                     gpointer         user_data)
+{
+        GsdSharingManager *manager = GSD_SHARING_MANAGER (user_data);
+
+        /* Check session pointer as a proxy for whether the manager is in the
+           start or stop state */
+        if (manager->priv->connection == NULL)
+                return NULL;
+
+        if (g_strcmp0 (property_name, "CurrentNetwork") == 0) {
+                return g_variant_new_string (manager->priv->current_network);
+        }
+
+        if (g_strcmp0 (property_name, "CurrentNetworkName") == 0) {
+                return g_variant_new_string (manager->priv->current_network_name);
+        }
+
+        if (g_strcmp0 (property_name, "CarrierType") == 0) {
+                return g_variant_new_string (manager->priv->carrier_type);
+        }
+
+        if (g_strcmp0 (property_name, "SharingStatus") == 0) {
+                return g_variant_new_uint32 (manager->priv->sharing_status);
+        }
+
+        return NULL;
+}
+
+static void
+handle_method_call (GDBusConnection       *connection,
+                    const gchar           *sender,
+                    const gchar           *object_path,
+                    const gchar           *interface_name,
+                    const gchar           *method_name,
+                    GVariant              *parameters,
+                    GDBusMethodInvocation *invocation,
+                    gpointer               user_data)
+{
+        GsdSharingManager *manager = (GsdSharingManager *) user_data;
+
+        g_debug ("Calling method '%s' for sharing", method_name);
+
+        /* Check session pointer as a proxy for whether the manager is in the
+           start or stop state */
+        if (manager->priv->connection == NULL)
+                return;
+
+        if (g_strcmp0 (method_name, "EnableService") == 0) {
+                const char *service;
+                GError *error = NULL;
+
+                g_variant_get (parameters, "(&s)", &service);
+                if (!gsd_sharing_manager_enable_service (manager, service, &error))
+                        g_dbus_method_invocation_take_error (invocation, error);
+                else
+                        g_dbus_method_invocation_return_value (invocation, NULL);
+        } else if (g_strcmp0 (method_name, "DisableService") == 0) {
+                const char *service;
+                const char *network_name;
+                GError *error = NULL;
+
+                g_variant_get (parameters, "(&s&s)", &service, &network_name);
+                if (!gsd_sharing_manager_disable_service (manager, service, network_name, &error))
+                        g_dbus_method_invocation_take_error (invocation, error);
+                else
+                        g_dbus_method_invocation_return_value (invocation, NULL);
+        } else if (g_strcmp0 (method_name, "ListNetworks") == 0) {
+                const char *service;
+                GError *error = NULL;
+                GVariant *variant;
+
+                g_variant_get (parameters, "(&s)", &service);
+                variant = gsd_sharing_manager_list_networks (manager, service, &error);
+                if (!variant)
+                        g_dbus_method_invocation_take_error (invocation, error);
+                else
+                        g_dbus_method_invocation_return_value (invocation, variant);
+        }
+}
+
+static const GDBusInterfaceVTable interface_vtable =
+{
+        handle_method_call,
+        handle_get_property,
+        NULL
+};
+
+static void
+on_bus_gotten (GObject               *source_object,
+               GAsyncResult          *res,
+               GsdSharingManager     *manager)
+{
+        GDBusConnection *connection;
+        GError *error = NULL;
+
+        connection = g_bus_get_finish (res, &error);
+        if (connection == NULL) {
+                if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+                        g_warning ("Could not get session bus: %s", error->message);
+                g_error_free (error);
+                return;
+        }
+        manager->priv->connection = connection;
+
+        g_dbus_connection_register_object (connection,
+                                           GSD_SHARING_DBUS_PATH,
+                                           manager->priv->introspection_data->interfaces[0],
+                                           &interface_vtable,
+                                           manager,
+                                           NULL,
+                                           NULL);
+
+        manager->priv->name_id = g_bus_own_name_on_connection (connection,
+                                                               GSD_SHARING_DBUS_NAME,
+                                                               G_BUS_NAME_OWNER_FLAGS_NONE,
+                                                               NULL,
+                                                               NULL,
+                                                               NULL,
+                                                               NULL);
+}
+
+#ifdef HAVE_NETWORK_MANAGER
+static void
+primary_connection_changed (GObject    *gobject,
+                            GParamSpec *pspec,
+                            gpointer    user_data)
+{
+        GsdSharingManager *manager = user_data;
+        NMActiveConnection *a_con;
+
+        a_con = nm_client_get_primary_connection (manager->priv->client);
+
+        g_clear_pointer (&manager->priv->current_network, g_free);
+        g_clear_pointer (&manager->priv->current_network_name, g_free);
+        g_clear_pointer (&manager->priv->carrier_type, g_free);
+
+        if (a_con) {
+                manager->priv->current_network = g_strdup (nm_active_connection_get_uuid (a_con));
+                manager->priv->current_network_name = g_strdup (nm_active_connection_get_id (a_con));
+                manager->priv->carrier_type = g_strdup (nm_active_connection_get_connection_type (a_con));
+                if (manager->priv->carrier_type == NULL)
+                        manager->priv->carrier_type = g_strdup ("");
+        } else {
+                manager->priv->current_network = g_strdup ("");
+                manager->priv->current_network_name = g_strdup ("");
+                manager->priv->carrier_type = g_strdup ("");
+        }
+
+        if (!a_con) {
+                manager->priv->sharing_status = GSD_SHARING_STATUS_OFFLINE;
+        } else if (*(manager->priv->carrier_type) == '\0') {
+                /* Missing carrier type information? */
+                manager->priv->sharing_status = GSD_SHARING_STATUS_OFFLINE;
+        } else if (g_str_equal (manager->priv->carrier_type, "bluetooth") ||
+                   g_str_equal (manager->priv->carrier_type, "gsm") ||
+                   g_str_equal (manager->priv->carrier_type, "cdma")) {
+                manager->priv->sharing_status = GSD_SHARING_STATUS_DISABLED_MOBILE_BROADBAND;
+        } else if (g_str_equal (manager->priv->carrier_type, "802-11-wireless")) {
+                if (connection_is_low_security (manager, manager->priv->current_network))
+                        manager->priv->sharing_status = GSD_SHARING_STATUS_DISABLED_LOW_SECURITY;
+                else
+                        manager->priv->sharing_status = GSD_SHARING_STATUS_AVAILABLE;
+        } else {
+                manager->priv->sharing_status = GSD_SHARING_STATUS_AVAILABLE;
+        }
+
+        g_debug ("current network: %s", manager->priv->current_network);
+        g_debug ("current network name: %s", manager->priv->current_network_name);
+        g_debug ("conn type: %s", manager->priv->carrier_type);
+        g_debug ("status: %d", manager->priv->sharing_status);
+
+        properties_changed (manager);
+        gsd_sharing_manager_sync_services (manager);
+}
+
+static void
+nm_client_ready (GObject      *source_object,
+                 GAsyncResult *res,
+                 gpointer      user_data)
+{
+        GsdSharingManager *manager = user_data;
+        GError *error = NULL;
+        NMClient *client;
+
+        client = nm_client_new_finish (res, &error);
+        if (!client) {
+                if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+                        g_warning ("Couldn't get NMClient: %s", error->message);
+                g_error_free (error);
+                return;
+        }
+        manager->priv->client = client;
+
+        g_signal_connect (G_OBJECT (client), "notify::primary-connection",
+                          G_CALLBACK (primary_connection_changed), manager);
+
+        primary_connection_changed (NULL, NULL, manager);
+}
+
+#endif /* HAVE_NETWORK_MANAGER */
+
+#define RYGEL_BUS_NAME "org.gnome.Rygel1"
+#define RYGEL_OBJECT_PATH "/org/gnome/Rygel1"
+#define RYGEL_INTERFACE_NAME "org.gnome.Rygel1"
+
+static void
+gsd_sharing_manager_disable_rygel (void)
+{
+	GDBusConnection *connection;
+	gchar *path;
+
+	path = g_build_filename (g_get_user_config_dir (), "autostart",
+				 "rygel.desktop", NULL);
+	if (!g_file_test (path, G_FILE_TEST_IS_SYMLINK | G_FILE_TEST_IS_REGULAR))
+                goto out;
+
+        g_unlink (path);
+
+	connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+	if (connection) {
+		g_dbus_connection_call (connection, RYGEL_BUS_NAME, RYGEL_OBJECT_PATH, RYGEL_INTERFACE_NAME,
+					"Shutdown", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1,
+					NULL, NULL, NULL);
+	}
+	g_object_unref (connection);
+
+ out:
+        g_free (path);
+}
+
+gboolean
+gsd_sharing_manager_start (GsdSharingManager *manager,
+                           GError           **error)
+{
+        g_debug ("Starting sharing manager");
+        gnome_settings_profile_start (NULL);
+
+        manager->priv->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+        g_assert (manager->priv->introspection_data != NULL);
+
+        gsd_sharing_manager_disable_rygel ();
+
+        manager->priv->cancellable = g_cancellable_new ();
+#ifdef HAVE_NETWORK_MANAGER
+        nm_client_new_async (manager->priv->cancellable, nm_client_ready, manager);
+#endif /* HAVE_NETWORK_MANAGER */
+
+        /* Start process of owning a D-Bus name */
+        g_bus_get (G_BUS_TYPE_SESSION,
+                   manager->priv->cancellable,
+                   (GAsyncReadyCallback) on_bus_gotten,
+                   manager);
+
+        gnome_settings_profile_end (NULL);
+        return TRUE;
+}
+
+void
+gsd_sharing_manager_stop (GsdSharingManager *manager)
+{
+        g_debug ("Stopping sharing manager");
+
+        manager->priv->sharing_status = GSD_SHARING_STATUS_OFFLINE;
+        gsd_sharing_manager_sync_services (manager);
+
+        if (manager->priv->cancellable) {
+                g_cancellable_cancel (manager->priv->cancellable);
+                g_clear_object (&manager->priv->cancellable);
+        }
+
+#ifdef HAVE_NETWORK_MANAGER
+        g_clear_object (&manager->priv->client);
+#endif /* HAVE_NETWORK_MANAGER */
+
+        if (manager->priv->name_id != 0) {
+                g_bus_unown_name (manager->priv->name_id);
+                manager->priv->name_id = 0;
+        }
+
+        g_clear_pointer (&manager->priv->introspection_data, g_dbus_node_info_unref);
+        g_clear_object (&manager->priv->connection);
+
+        g_clear_pointer (&manager->priv->current_network, g_free);
+        g_clear_pointer (&manager->priv->current_network_name, g_free);
+        g_clear_pointer (&manager->priv->carrier_type, g_free);
+}
+
+static void
+gsd_sharing_manager_class_init (GsdSharingManagerClass *klass)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->finalize = gsd_sharing_manager_finalize;
+
+        g_type_class_add_private (klass, sizeof (GsdSharingManagerPrivate));
+}
+
+static void
+service_free (gpointer pointer)
+{
+        ServiceInfo *service = pointer;
+
+        g_clear_object (&service->settings);
+        g_free (service);
+}
+
+static void
+gsd_sharing_manager_init (GsdSharingManager *manager)
+{
+        guint i;
+
+        manager->priv = GSD_SHARING_MANAGER_GET_PRIVATE (manager);
+        manager->priv->services = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, service_free);
+
+        /* Default state */
+        manager->priv->current_network = g_strdup ("");
+        manager->priv->current_network_name = g_strdup ("");
+        manager->priv->carrier_type = g_strdup ("");
+        manager->priv->sharing_status = GSD_SHARING_STATUS_OFFLINE;
+
+        for (i = 0; i < G_N_ELEMENTS (services); i++) {
+                ServiceInfo *service;
+                char *path;
+
+                service = g_new0 (ServiceInfo, 1);
+                service->name = services[i];
+                path = g_strdup_printf ("/org/gnome/settings-daemon/plugins/sharing/%s/", services[i]);
+                service->settings = g_settings_new_with_path ("org.gnome.settings-daemon.plugins.sharing.service", path);
+                g_free (path);
+
+                g_hash_table_insert (manager->priv->services, (gpointer) services[i], service);
+        }
+}
+
+static void
+gsd_sharing_manager_finalize (GObject *object)
+{
+        GsdSharingManager *manager;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GSD_IS_SHARING_MANAGER (object));
+
+        manager = GSD_SHARING_MANAGER (object);
+
+        g_return_if_fail (manager->priv != NULL);
+
+        gsd_sharing_manager_stop (manager);
+
+        g_hash_table_unref (manager->priv->services);
+
+        G_OBJECT_CLASS (gsd_sharing_manager_parent_class)->finalize (object);
+}
+
+GsdSharingManager *
+gsd_sharing_manager_new (void)
+{
+        if (manager_object != NULL) {
+                g_object_ref (manager_object);
+        } else {
+                manager_object = g_object_new (GSD_TYPE_SHARING_MANAGER, NULL);
+                g_object_add_weak_pointer (manager_object,
+                                           (gpointer *) &manager_object);
+        }
+
+        return GSD_SHARING_MANAGER (manager_object);
+}

=== added file 'plugins/sharing/gsd-sharing-manager.h'
--- plugins/sharing/gsd-sharing-manager.h	1970-01-01 00:00:00 +0000
+++ plugins/sharing/gsd-sharing-manager.h	2018-09-30 12:23:49 +0000
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <[email protected]>
+ *
+ * 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 2 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/>.
+ *
+ */
+
+#ifndef __GSD_SHARING_MANAGER_H
+#define __GSD_SHARING_MANAGER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GSD_TYPE_SHARING_MANAGER         (gsd_sharing_manager_get_type ())
+#define GSD_SHARING_MANAGER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_SHARING_MANAGER, GsdSharingManager))
+#define GSD_SHARING_MANAGER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_SHARING_MANAGER, GsdSharingManagerClass))
+#define GSD_IS_SHARING_MANAGER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_SHARING_MANAGER))
+#define GSD_IS_SHARING_MANAGER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_SHARING_MANAGER))
+#define GSD_SHARING_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_SHARING_MANAGER, GsdSharingManagerClass))
+
+typedef struct GsdSharingManagerPrivate GsdSharingManagerPrivate;
+
+typedef struct
+{
+        GObject                     parent;
+        GsdSharingManagerPrivate *priv;
+} GsdSharingManager;
+
+typedef struct
+{
+        GObjectClass   parent_class;
+} GsdSharingManagerClass;
+
+GType                   gsd_sharing_manager_get_type            (void);
+
+GsdSharingManager *       gsd_sharing_manager_new                 (void);
+gboolean                gsd_sharing_manager_start               (GsdSharingManager *manager,
+                                                               GError         **error);
+void                    gsd_sharing_manager_stop                (GsdSharingManager *manager);
+
+G_END_DECLS
+
+#endif /* __GSD_SHARING_MANAGER_H */

=== added file 'plugins/sharing/gsd-sharing-plugin.c'
--- plugins/sharing/gsd-sharing-plugin.c	1970-01-01 00:00:00 +0000
+++ plugins/sharing/gsd-sharing-plugin.c	2018-09-30 12:23:49 +0000
@@ -0,0 +1,28 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <[email protected]>
+ *
+ * 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 2, 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 "config.h"
+
+#include <glib/gi18n-lib.h>
+#include <gmodule.h>
+
+#include "gnome-settings-plugin.h"
+#include "gsd-sharing-manager.h"
+
+GNOME_SETTINGS_PLUGIN_REGISTER (GsdSharing, gsd_sharing)

=== added file 'plugins/sharing/sharing.gnome-settings-plugin.in'
--- plugins/sharing/sharing.gnome-settings-plugin.in	1970-01-01 00:00:00 +0000
+++ plugins/sharing/sharing.gnome-settings-plugin.in	2018-09-30 12:23:49 +0000
@@ -0,0 +1,9 @@
+[GNOME Settings Plugin]
+Module=sharing
+IAge=0
+# 100 is the default load Priority
+Priority=100
+Name=Sharing
+Description=Sharing plugin
+Authors=Bastien Nocera <[email protected]>
+Copyright=Copyright © 2014 AUTHOR

=== added file 'plugins/sharing/test-sharing.c'
--- plugins/sharing/test-sharing.c	1970-01-01 00:00:00 +0000
+++ plugins/sharing/test-sharing.c	2018-09-30 12:23:49 +0000
@@ -0,0 +1,7 @@
+#define NEW gsd_sharing_manager_new
+#define START gsd_sharing_manager_start
+#define STOP gsd_sharing_manager_stop
+#define MANAGER GsdSharingManager
+#include "gsd-sharing-manager.h"
+
+#include "test-plugin.h"

-- 
ubuntu-desktop mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-desktop

Reply via email to