rework deprecated g_type_class_add_private()
[platform/core/system/tlm.git] / src / daemon / dbus / tlm-dbus-login-adapter.c
1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4  * This file is part of tlm
5  *
6  * Copyright (C) 2014 Intel Corporation.
7  *
8  * Contact: Imran Zaman <imran.zaman@intel.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  */
25
26 #include "config.h"
27
28 #include "common/tlm-log.h"
29 #include "common/tlm-error.h"
30 #include "common/dbus/tlm-dbus.h"
31
32 #include "tlm-dbus-login-adapter.h"
33
34 enum
35 {
36     PROP_0,
37
38     PROP_CONNECTION,
39
40     N_PROPERTIES
41 };
42
43 static GParamSpec *properties[N_PROPERTIES];
44
45 struct _TlmDbusLoginAdapterPrivate
46 {
47     GDBusConnection *connection;
48     TlmDbusLogin *dbus_obj;
49 };
50
51 G_DEFINE_TYPE_WITH_PRIVATE (TlmDbusLoginAdapter, tlm_dbus_login_adapter, G_TYPE_OBJECT)
52
53 enum {
54     SIG_LOGIN_USER,
55     SIG_LOGOUT_USER,
56     SIG_SWITCH_USER,
57
58     SIG_MAX
59 };
60
61 static guint signals[SIG_MAX];
62
63 static gboolean
64 _handle_login_user (
65         TlmDbusLoginAdapter *self,
66         GDBusMethodInvocation *invocation,
67         const gchar *seat_id,
68         const gchar *username,
69         const gchar *password,
70         const GVariant *environ,
71         gpointer user_data);
72
73 static gboolean
74 _handle_switch_user (
75         TlmDbusLoginAdapter *self,
76         GDBusMethodInvocation *invocation,
77         const gchar *seat_id,
78         const gchar *username,
79         const gchar *password,
80         const GVariant *environ,
81         gpointer user_data);
82
83 static gboolean
84 _handle_logout_user (
85         TlmDbusLoginAdapter *self,
86         GDBusMethodInvocation *invocation,
87         const gchar *seat_id,
88         gpointer user_data);
89
90 static void
91 _set_property (
92         GObject *object,
93         guint property_id,
94         const GValue *value,
95         GParamSpec *pspec)
96 {
97     TlmDbusLoginAdapter *self = TLM_DBUS_LOGIN_ADAPTER (object);
98
99     switch (property_id) {
100         case PROP_CONNECTION:
101             self->priv->connection = g_value_dup_object (value);
102             break;
103         default:
104             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
105     }
106 }
107
108 static void
109 _get_property (
110         GObject *object,
111         guint property_id,
112         GValue *value,
113         GParamSpec *pspec)
114 {
115     TlmDbusLoginAdapter *self = TLM_DBUS_LOGIN_ADAPTER (object);
116
117     switch (property_id) {
118         case PROP_CONNECTION:
119             g_value_set_object (value, self->priv->connection);
120             break;
121         default:
122             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
123     }
124 }
125
126 static void
127 _dispose (
128         GObject *object)
129 {
130     TlmDbusLoginAdapter *self = TLM_DBUS_LOGIN_ADAPTER (object);
131
132     DBG("- unregistering dbus login adaptor %p.", self);
133
134     if (self->priv->dbus_obj) {
135         g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (
136                 self->priv->dbus_obj));
137         g_object_unref (self->priv->dbus_obj);
138         self->priv->dbus_obj = NULL;
139     }
140
141     if (self->priv->connection) {
142         /* NOTE: There seems to be some bug in glib's dbus connection's
143          * worker thread such that it does not closes the stream. The problem
144          * is hard to be tracked exactly as it is more of timing issue.
145          * Following code snippet at least closes the stream to avoid any
146          * descriptors leak.
147          * */
148         GIOStream *stream = g_dbus_connection_get_stream (
149                 self->priv->connection);
150         if (stream) g_io_stream_close (stream, NULL, NULL);
151         g_object_unref (self->priv->connection);
152         self->priv->connection = NULL;
153     }
154
155     G_OBJECT_CLASS (tlm_dbus_login_adapter_parent_class)->dispose (
156             object);
157 }
158
159 static void
160 _finalize (
161         GObject *object)
162 {
163
164     G_OBJECT_CLASS (tlm_dbus_login_adapter_parent_class)->finalize (
165             object);
166 }
167
168 static void
169 tlm_dbus_login_adapter_class_init (
170         TlmDbusLoginAdapterClass *klass)
171 {
172     GObjectClass* object_class = G_OBJECT_CLASS (klass);
173
174     object_class->get_property = _get_property;
175     object_class->set_property = _set_property;
176     object_class->dispose = _dispose;
177     object_class->finalize = _finalize;
178
179     properties[PROP_CONNECTION] = g_param_spec_object (
180             "connection",
181             "Bus connection",
182             "DBus connection used",
183             G_TYPE_DBUS_CONNECTION,
184             G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
185
186     g_object_class_install_properties (object_class, N_PROPERTIES, properties);
187
188     signals[SIG_LOGIN_USER] = g_signal_new ("login-user",
189             TLM_TYPE_LOGIN_ADAPTER,
190             G_SIGNAL_RUN_LAST,
191             0,
192             NULL,
193             NULL,
194             NULL,
195             G_TYPE_NONE,
196             5,
197             G_TYPE_STRING,
198             G_TYPE_STRING,
199             G_TYPE_STRING,
200             G_TYPE_VARIANT,
201             G_TYPE_DBUS_METHOD_INVOCATION);
202
203     signals[SIG_LOGOUT_USER] = g_signal_new ("logout-user",
204             TLM_TYPE_LOGIN_ADAPTER,
205             G_SIGNAL_RUN_LAST,
206             0,
207             NULL,
208             NULL,
209             NULL,
210             G_TYPE_NONE,
211             2,
212             G_TYPE_STRING,
213             G_TYPE_DBUS_METHOD_INVOCATION);
214
215     signals[SIG_SWITCH_USER] = g_signal_new ("switch-user",
216             TLM_TYPE_LOGIN_ADAPTER,
217             G_SIGNAL_RUN_LAST,
218             0,
219             NULL,
220             NULL,
221             NULL,
222             G_TYPE_NONE,
223             5,
224             G_TYPE_STRING,
225             G_TYPE_STRING,
226             G_TYPE_STRING,
227             G_TYPE_VARIANT,
228             G_TYPE_DBUS_METHOD_INVOCATION);
229 }
230
231 static void
232 tlm_dbus_login_adapter_init (TlmDbusLoginAdapter *self)
233 {
234     self->priv = tlm_dbus_login_adapter_get_instance_private (self);
235
236     self->priv->connection = 0;
237     self->priv->dbus_obj = tlm_dbus_login_skeleton_new ();
238 }
239
240 static gboolean
241 _handle_login_user (
242         TlmDbusLoginAdapter *self,
243         GDBusMethodInvocation *invocation,
244         const gchar *seat_id,
245         const gchar *username,
246         const gchar *password,
247         const GVariant *environment,
248         gpointer emitter)
249 {
250     GError *error = NULL;
251
252     g_return_val_if_fail (self && TLM_IS_DBUS_LOGIN_ADAPTER(self), FALSE);
253
254     if (!seat_id || !username || !password) {
255         error = TLM_GET_ERROR_FOR_ID (TLM_ERROR_INVALID_INPUT,
256                 "Invalid input");
257         g_dbus_method_invocation_return_gerror (invocation, error);
258         g_error_free (error);
259         return TRUE;
260     }
261     DBG ("Emit login-user signal: seat_id=%s, username=%s", seat_id, username);
262
263     g_signal_emit (self, signals[SIG_LOGIN_USER], 0, seat_id, username,
264             password, environment, invocation);
265
266     return TRUE;
267 }
268
269 static gboolean
270 _handle_logout_user (
271         TlmDbusLoginAdapter *self,
272         GDBusMethodInvocation *invocation,
273         const gchar *seat_id,
274         gpointer emitter)
275 {
276     GError *error = NULL;
277
278     g_return_val_if_fail (self && TLM_IS_DBUS_LOGIN_ADAPTER(self),
279             FALSE);
280
281     if (!seat_id) {
282         error = TLM_GET_ERROR_FOR_ID (TLM_ERROR_INVALID_INPUT,
283                 "Invalid input");
284         g_dbus_method_invocation_return_gerror (invocation, error);
285         g_error_free (error);
286         return TRUE;
287     }
288     DBG ("Emit logout-user signal: seat_id=%s", seat_id);
289
290     g_signal_emit (self, signals[SIG_LOGOUT_USER], 0, seat_id, invocation);
291
292     return TRUE;
293 }
294
295 static gboolean
296 _handle_switch_user (
297         TlmDbusLoginAdapter *self,
298         GDBusMethodInvocation *invocation,
299         const gchar *seat_id,
300         const gchar *username,
301         const gchar *password,
302         const GVariant *environment,
303         gpointer emitter)
304 {
305     GError *error = NULL;
306
307     g_return_val_if_fail (self && TLM_IS_DBUS_LOGIN_ADAPTER(self),
308             FALSE);
309
310     if (!seat_id || !username || !password) {
311         error = TLM_GET_ERROR_FOR_ID (TLM_ERROR_INVALID_INPUT,
312                 "Invalid input");
313         g_dbus_method_invocation_return_gerror (invocation, error);
314         g_error_free (error);
315         return TRUE;
316     }
317     DBG ("Emit switch-user signal: seat_id=%s, username=%s", seat_id, username);
318
319     g_signal_emit (self, signals[SIG_SWITCH_USER], 0, seat_id, username,
320             password, environment, invocation);
321
322     return TRUE;
323 }
324
325 TlmDbusLoginAdapter *
326 tlm_dbus_login_adapter_new_with_connection (
327         GDBusConnection *bus_connection)
328 {
329     GError *err = NULL;
330     TlmDbusLoginAdapter *adapter = TLM_DBUS_LOGIN_ADAPTER (g_object_new (
331             TLM_TYPE_LOGIN_ADAPTER, "connection", bus_connection, NULL));
332
333     if (!g_dbus_interface_skeleton_export (
334             G_DBUS_INTERFACE_SKELETON(adapter->priv->dbus_obj),
335             adapter->priv->connection, TLM_LOGIN_OBJECTPATH, &err)) {
336         WARN ("failed to register object: %s", err->message);
337         g_error_free (err);
338         g_object_unref (adapter);
339         return NULL;
340     }
341
342     DBG("(+) started login interface '%p' at path '%s' on connection"
343             " '%p'", adapter, TLM_LOGIN_OBJECTPATH, bus_connection);
344
345     g_signal_connect_swapped (adapter->priv->dbus_obj,
346         "handle-login-user", G_CALLBACK (_handle_login_user), adapter);
347     g_signal_connect_swapped (adapter->priv->dbus_obj,
348         "handle-logout-user", G_CALLBACK(_handle_logout_user), adapter);
349     g_signal_connect_swapped (adapter->priv->dbus_obj,
350         "handle-switch-user", G_CALLBACK(_handle_switch_user), adapter);
351
352     return adapter;
353 }
354
355 void
356 tlm_dbus_login_adapter_request_completed (
357         TlmDbusRequest *request,
358         GError *error)
359 {
360     g_return_if_fail (request && request->dbus_adapter &&
361             TLM_IS_DBUS_LOGIN_ADAPTER(request->dbus_adapter));
362
363     TlmDbusLoginAdapter *adapter = TLM_DBUS_LOGIN_ADAPTER (
364             request->dbus_adapter);
365     if (error) {
366         g_dbus_method_invocation_return_gerror (request->invocation, error);
367         return;
368     }
369
370     switch (request->type) {
371     case TLM_DBUS_REQUEST_TYPE_LOGIN_USER:
372         tlm_dbus_login_complete_login_user (adapter->priv->dbus_obj,
373                 request->invocation);
374         break;
375     case TLM_DBUS_REQUEST_TYPE_LOGOUT_USER:
376         tlm_dbus_login_complete_logout_user (adapter->priv->dbus_obj,
377                 request->invocation);
378         break;
379     case TLM_DBUS_REQUEST_TYPE_SWITCH_USER:
380         tlm_dbus_login_complete_switch_user (adapter->priv->dbus_obj,
381                 request->invocation);
382         break;
383     }
384 }