~azzar1/unity/fix-839717-5.0

1997.2.1 by Gord Allott
adds a gdbus test and service
1
#include "test_service_gdbus_wrapper.h"
2
#include <unity.h>
3
#include <gio/gio.h>
4
5
const char * gdbus_wrapper_interface = 
6
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
7
"<node name=\"/\">\n"
8
"        <interface name=\"com.canonical.gdbus_wrapper\">\n"
9
"<!-- Properties -->\n"
10
"                <!-- None -->\n"
11
"\n"
12
"<!-- Functions -->\n"
13
"                <method name=\"TestMethod\">\n"
14
"                        <!-- in -->\n"
15
"                        <arg type=\"s\" name=\"query\" direction=\"in\" />\n"
16
"                        <!-- out -->\n"
17
"                        <arg type=\"s\" name=\"target\" direction=\"out\" />\n"
18
"                </method>\n"
19
"\n"
20
"<!-- Signals -->\n"
21
"                <signal name=\"TestSignal\">\n"
22
"                        <arg type=\"s\" name=\"target\" direction=\"out\" />\n"
23
"                </signal>\n"
24
"\n"
25
"<!-- End of interesting stuff -->\n"
26
"\n"
27
"        </interface>\n"
28
"</node>\n"
29
;
30
static void bus_got_cb          (GObject *object, GAsyncResult * res, gpointer user_data);
31
static void bus_method          (GDBusConnection *connection,
32
                                const gchar *sender,
33
                                const gchar *object_path,
34
                                const gchar *interface_name,
35
                                const gchar *method_name,
36
                                GVariant *parameters,
37
                                GDBusMethodInvocation *invocation,
38
                                gpointer user_data);
39
40
G_DEFINE_TYPE(ServiceGDBusWrapper, service_gdbus_wrapper, G_TYPE_OBJECT);
41
static GDBusNodeInfo * node_info = NULL;
42
static GDBusInterfaceInfo * iface_info = NULL;
43
static GDBusInterfaceVTable bus_vtable = {
44
  method_call: bus_method,
45
  get_property: NULL,
46
  set_property: NULL,
47
};
48
49
50
struct _ServiceGDBusWrapperPrivate
51
{
52
  GDBusConnection * bus;
53
  GCancellable * bus_lookup;
54
  guint bus_registration;
55
};
56
57
static void
58
service_gdbus_wrapper_dispose(GObject* object)
59
{
60
  ServiceGDBusWrapper* self = SERVICE_GDBUS_WRAPPER(object);
61
  if (self->priv->bus_lookup != NULL) {
62
    g_cancellable_cancel(self->priv->bus_lookup);
63
    g_object_unref(self->priv->bus_lookup);
64
    self->priv->bus_lookup = NULL;
65
  }
66
67
  if (self->priv->bus_registration != 0) {
68
    g_dbus_connection_unregister_object(self->priv->bus, self->priv->bus_registration);
69
    self->priv->bus_registration = 0;
70
  }
71
72
  if (self->priv->bus != NULL) {
73
    g_object_unref(self->priv->bus);
74
    self->priv->bus = NULL;
75
  }
76
77
}
78
79
static void
80
service_gdbus_wrapper_class_init(ServiceGDBusWrapperClass* klass)
81
{
82
  G_OBJECT_CLASS(klass)->dispose = service_gdbus_wrapper_dispose;
83
  g_type_class_add_private (klass, sizeof (ServiceGDBusWrapperPrivate));
84
85
  if (node_info == NULL) 
86
  {
87
    GError * error = NULL;
88
89
    node_info = g_dbus_node_info_new_for_xml(gdbus_wrapper_interface, &error);
90
    if (error != NULL) 
91
    {
92
        g_error("Unable to parse GDBUS_WRAPPER interface: %s", error->message);
93
        g_error_free(error);
94
    }
95
  }
96
97
  if (node_info != NULL && iface_info == NULL) 
98
  {
99
    iface_info = g_dbus_node_info_lookup_interface(node_info,"com.canonical.gdbus_wrapper");
100
    if (iface_info == NULL) 
101
    {
102
      g_error("Unable to find interface 'com.canonical.gdbus_wrapper'");
103
    }
104
  }
105
106
}
107
108
static void
109
service_gdbus_wrapper_init(ServiceGDBusWrapper* self)
110
{
111
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, SERVICE_TYPE_GDBUS_WRAPPER, ServiceGDBusWrapperPrivate);
112
  self->priv->bus = NULL;
113
  self->priv->bus_lookup = NULL;
114
  self->priv->bus_registration = 0;
115
  
116
  self->priv->bus_lookup = g_cancellable_new();
117
  g_bus_get(G_BUS_TYPE_SESSION, self->priv->bus_lookup, bus_got_cb, self);
118
  
119
}
120
121
ServiceGDBusWrapper*
122
service_gdbus_wrapper_new()
123
{
124
  return g_object_new(SERVICE_TYPE_GDBUS_WRAPPER, NULL);
125
}
126
127
static void
128
bus_got_cb (GObject *object, GAsyncResult * res, gpointer user_data)
129
{
130
  GError * error = NULL;
131
  ServiceGDBusWrapper * self = SERVICE_GDBUS_WRAPPER(user_data);
132
  GDBusConnection * bus;
133
134
  bus = g_bus_get_finish(res, &error);
135
  if (error != NULL) {
136
    g_critical("Unable to get bus: %s", error->message);
137
    g_error_free(error);
138
    return;
139
  }
140
141
  self->priv->bus = bus;
142
143
  /* Register object */
144
  self->priv->bus_registration = g_dbus_connection_register_object(bus,
145
                                                  /* path */       "/com/canonical/gdbus_wrapper",
146
                                                  /* interface */  iface_info,
147
                                                  /* vtable */     &bus_vtable,
148
                                                  /* userdata */   self,
149
                                                  /* destroy */    NULL,
150
                                                  /* error */      &error);
151
152
  if (error != NULL) {
153
    g_critical ("Unable to create bus connection object, %s", error->message);
154
    g_error_free(error);
155
    return;
156
  }
157
  
158
  return;
159
}
160
161
static void
162
bus_method (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data)
163
{ 
164
  if (g_strcmp0(method_name, "TestMethod") == 0) 
165
  {
166
    GVariant * ret = NULL;
167
    GVariant * sig_data = NULL;
168
    GVariant * tmp = NULL;
169
    gchar * query = NULL;
170
    GError * error = NULL;
171
    g_variant_get(parameters, "(s)", &query);
172
    
173
    tmp = g_variant_new_string(query);
174
    ret = g_variant_new_tuple(&tmp, 1);
175
    g_dbus_method_invocation_return_value(invocation, ret);
176
    tmp = NULL; 
177
     
178
    // emit a signal with the same string as passed in every time this method is called
179
    
180
    tmp = g_variant_new_string(query);
181
    sig_data = g_variant_new_tuple(&tmp, 1);    
182
    g_dbus_connection_emit_signal(connection,
183
                                  NULL,                            /* destination bus, we don't care */
184
                                  "/com/canonical/gdbus_wrapper",  /* object path */
185
                                  "com.canonical.gdbus_wrapper",   /* interface name */
186
                                  "TestSignal",                    /* Signal name */
187
                                  sig_data,                        /* parameter */
188
                                  &error);                         /* error */
189
                                    
190
    if (error != NULL)
191
    {
192
      g_critical ("could not emit signal TestSignal with data %s", query);
193
      g_error_free(error);
194
    }
195
196
    g_free(query);
197
  }
198
199
  return;
200
}
201