Merge lp:~robert-ancell/lightdm/liblightdm-async into lp:lightdm
- liblightdm-async
- Merge into trunk
Proposed by
Robert Ancell
Status: | Merged |
---|---|
Merged at revision: | 1975 |
Proposed branch: | lp:~robert-ancell/lightdm/liblightdm-async |
Merge into: | lp:lightdm |
Diff against target: |
997 lines (+442/-114) 7 files modified
debian/liblightdm-gobject-1-0.symbols (+6/-0) doc/lightdm-gobject-1-sections.txt (+6/-0) doc/tmpl/greeter.sgml (+67/-0) liblightdm-gobject/greeter.c (+255/-52) liblightdm-gobject/liblightdm-gobject-1.vapi (+4/-0) liblightdm-gobject/lightdm/greeter.h (+14/-1) tests/src/test-gobject-greeter.c (+90/-61) |
To merge this branch: | bzr merge lp:~robert-ancell/lightdm/liblightdm-async |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
LightDM Development Team | Pending | ||
Review via email: mp+217532@code.launchpad.net |
Commit message
Add asynchronous methods to liblightdm - lightdm_
Description of the change
To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : | # |
review:
Needs Fixing
(continuous-integration)
- 1955. By Robert Ancell
-
Update documentation
- 1956. By Robert Ancell
-
Merge with trunk
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'debian/liblightdm-gobject-1-0.symbols' |
2 | --- debian/liblightdm-gobject-1-0.symbols 2014-04-28 14:33:32 +0000 |
3 | +++ debian/liblightdm-gobject-1-0.symbols 2014-04-29 01:26:07 +0000 |
4 | @@ -16,7 +16,11 @@ |
5 | lightdm_greeter_authenticate_remote@Base 1.3.3 |
6 | lightdm_greeter_cancel_authentication@Base 0.9.2 |
7 | lightdm_greeter_cancel_autologin@Base 0.9.2 |
8 | + lightdm_greeter_connect@Base 1.11.1 |
9 | + lightdm_greeter_connect_finish@Base 1.11.1 |
10 | lightdm_greeter_connect_sync@Base 0.9.2 |
11 | + lightdm_greeter_ensure_shared_data_dir@Base 1.11.1 |
12 | + lightdm_greeter_ensure_shared_data_dir_finish@Base 1.11.1 |
13 | lightdm_greeter_ensure_shared_data_dir_sync@Base 1.9.8 |
14 | lightdm_greeter_get_authentication_user@Base 0.9.2 |
15 | lightdm_greeter_get_autologin_guest_hint@Base 0.9.2 |
16 | @@ -38,6 +42,8 @@ |
17 | lightdm_greeter_respond@Base 0.9.2 |
18 | lightdm_greeter_set_language@Base 0.9.8 |
19 | lightdm_greeter_set_resettable@Base 1.11.1 |
20 | + lightdm_greeter_start_session@Base 1.11.1 |
21 | + lightdm_greeter_start_session_finish@Base 1.11.1 |
22 | lightdm_greeter_start_session_sync@Base 0.9.2 |
23 | lightdm_hibernate@Base 0.9.2 |
24 | lightdm_language_get_code@Base 0.9.2 |
25 | |
26 | === modified file 'doc/lightdm-gobject-1-sections.txt' |
27 | --- doc/lightdm-gobject-1-sections.txt 2014-04-29 01:22:06 +0000 |
28 | +++ doc/lightdm-gobject-1-sections.txt 2014-04-29 01:26:07 +0000 |
29 | @@ -133,7 +133,11 @@ |
30 | LightDMPromptType |
31 | lightdm_greeter_new |
32 | lightdm_greeter_set_resettable |
33 | +lightdm_greeter_connect |
34 | +lightdm_greeter_connect_finish |
35 | lightdm_greeter_connect_sync |
36 | +lightdm_greeter_ensure_shared_data_dir |
37 | +lightdm_greeter_ensure_shared_data_dir_finish |
38 | lightdm_greeter_ensure_shared_data_dir_sync |
39 | lightdm_greeter_get_default_session_hint |
40 | lightdm_greeter_get_hint |
41 | @@ -158,6 +162,8 @@ |
42 | lightdm_greeter_get_in_authentication |
43 | lightdm_greeter_get_is_authenticated |
44 | lightdm_greeter_get_authentication_user |
45 | +lightdm_greeter_start_session |
46 | +lightdm_greeter_start_session_finish |
47 | lightdm_greeter_start_session_sync |
48 | <SUBSECTION Standard> |
49 | LIGHTDM_GREETER |
50 | |
51 | === modified file 'doc/tmpl/greeter.sgml' |
52 | --- doc/tmpl/greeter.sgml 2014-04-29 01:22:06 +0000 |
53 | +++ doc/tmpl/greeter.sgml 2014-04-29 01:26:07 +0000 |
54 | @@ -155,6 +155,28 @@ |
55 | @resettable: |
56 | |
57 | |
58 | +<!-- ##### FUNCTION lightdm_greeter_connect ##### --> |
59 | +<para> |
60 | + |
61 | +</para> |
62 | + |
63 | +@greeter: |
64 | +@cancellable: |
65 | +@callback: |
66 | +@user_data: |
67 | + |
68 | + |
69 | +<!-- ##### FUNCTION lightdm_greeter_connect_finish ##### --> |
70 | +<para> |
71 | + |
72 | +</para> |
73 | + |
74 | +@greeter: |
75 | +@result: |
76 | +@error: |
77 | +@Returns: |
78 | + |
79 | + |
80 | <!-- ##### FUNCTION lightdm_greeter_connect_sync ##### --> |
81 | <para> |
82 | |
83 | @@ -165,6 +187,28 @@ |
84 | @Returns: |
85 | |
86 | |
87 | +<!-- ##### FUNCTION lightdm_greeter_ensure_shared_data_dir ##### --> |
88 | +<para> |
89 | + |
90 | +</para> |
91 | + |
92 | +@greeter: |
93 | +@username: |
94 | +@cancellable: |
95 | +@callback: |
96 | +@user_data: |
97 | + |
98 | + |
99 | +<!-- ##### FUNCTION lightdm_greeter_ensure_shared_data_dir_finish ##### --> |
100 | +<para> |
101 | + |
102 | +</para> |
103 | + |
104 | +@greeter: |
105 | +@result: |
106 | +@Returns: |
107 | + |
108 | + |
109 | <!-- ##### FUNCTION lightdm_greeter_ensure_shared_data_dir_sync ##### --> |
110 | <para> |
111 | |
112 | @@ -380,6 +424,29 @@ |
113 | @Returns: |
114 | |
115 | |
116 | +<!-- ##### FUNCTION lightdm_greeter_start_session ##### --> |
117 | +<para> |
118 | + |
119 | +</para> |
120 | + |
121 | +@greeter: |
122 | +@session: |
123 | +@cancellable: |
124 | +@callback: |
125 | +@user_data: |
126 | + |
127 | + |
128 | +<!-- ##### FUNCTION lightdm_greeter_start_session_finish ##### --> |
129 | +<para> |
130 | + |
131 | +</para> |
132 | + |
133 | +@greeter: |
134 | +@result: |
135 | +@error: |
136 | +@Returns: |
137 | + |
138 | + |
139 | <!-- ##### FUNCTION lightdm_greeter_start_session_sync ##### --> |
140 | <para> |
141 | |
142 | |
143 | === modified file 'liblightdm-gobject/greeter.c' |
144 | --- liblightdm-gobject/greeter.c 2014-04-28 22:56:38 +0000 |
145 | +++ liblightdm-gobject/greeter.c 2014-04-29 01:26:07 +0000 |
146 | @@ -125,6 +125,9 @@ |
147 | typedef struct |
148 | { |
149 | GObject parent_instance; |
150 | + GCancellable *cancellable; |
151 | + GAsyncReadyCallback callback; |
152 | + gpointer user_data; |
153 | gboolean complete; |
154 | guint32 return_code; |
155 | gchar *dir; |
156 | @@ -134,8 +137,9 @@ |
157 | GObjectClass parent_class; |
158 | } RequestClass; |
159 | GType request_get_type (void); |
160 | +static void request_iface_init (GAsyncResultIface *iface); |
161 | #define REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), request_get_type (), Request)) |
162 | -G_DEFINE_TYPE (Request, request, G_TYPE_OBJECT); |
163 | +G_DEFINE_TYPE_WITH_CODE (Request, request, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, request_iface_init)); |
164 | |
165 | /** |
166 | * lightdm_greeter_new: |
167 | @@ -172,15 +176,33 @@ |
168 | } |
169 | |
170 | static Request * |
171 | -request_new (void) |
172 | +request_new (GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) |
173 | { |
174 | Request *request; |
175 | |
176 | request = g_object_new (request_get_type (), NULL); |
177 | + if (cancellable) |
178 | + request->cancellable = g_object_ref (cancellable); |
179 | + request->callback = callback; |
180 | + request->user_data = user_data; |
181 | |
182 | return request; |
183 | } |
184 | |
185 | +static void |
186 | +request_complete (Request *request, GObject *object) |
187 | +{ |
188 | + request->complete = TRUE; |
189 | + |
190 | + if (!request->callback) |
191 | + return; |
192 | + |
193 | + if (request->cancellable && g_cancellable_is_cancelled (request->cancellable)) |
194 | + return; |
195 | + |
196 | + request->callback (object, G_ASYNC_RESULT (request), request->user_data); |
197 | +} |
198 | + |
199 | static gboolean |
200 | timed_login_cb (gpointer data) |
201 | { |
202 | @@ -288,14 +310,17 @@ |
203 | return read_int (message, message_length, &offset); |
204 | } |
205 | |
206 | -static void |
207 | -write_message (LightDMGreeter *greeter, guint8 *message, gsize message_length) |
208 | +static gboolean |
209 | +send_message (LightDMGreeter *greeter, guint8 *message, gsize message_length) |
210 | { |
211 | LightDMGreeterPrivate *priv = GET_PRIVATE (greeter); |
212 | GIOStatus status; |
213 | GError *error = NULL; |
214 | guint32 stated_length; |
215 | |
216 | + if (!priv->to_server_channel) |
217 | + return FALSE; |
218 | + |
219 | /* Double check that we're sending well-formed messages. If we say we're |
220 | sending more than we do, we end up DOS'ing lightdm as it waits for the |
221 | rest. If we say we're sending less than we do, we confuse the heck out |
222 | @@ -305,16 +330,20 @@ |
223 | if (stated_length != message_length) |
224 | { |
225 | g_warning ("Refusing to write malformed packet to daemon: declared size is %u, but actual size is %zu", stated_length, message_length); |
226 | - return; |
227 | + return FALSE; |
228 | } |
229 | |
230 | status = g_io_channel_write_chars (priv->to_server_channel, (gchar *) message, message_length, NULL, &error); |
231 | if (error) |
232 | g_warning ("Error writing to daemon: %s", error->message); |
233 | g_clear_error (&error); |
234 | - if (status == G_IO_STATUS_NORMAL) |
235 | - g_debug ("Wrote %zi bytes to daemon", message_length); |
236 | + if (status != G_IO_STATUS_NORMAL) |
237 | + return FALSE; |
238 | + |
239 | + g_debug ("Wrote %zi bytes to daemon", message_length); |
240 | g_io_channel_flush (priv->to_server_channel, NULL); |
241 | + |
242 | + return TRUE; |
243 | } |
244 | |
245 | static void |
246 | @@ -351,10 +380,11 @@ |
247 | priv->autologin_timeout = g_timeout_add (timeout * 1000, timed_login_cb, greeter); |
248 | } |
249 | |
250 | + /* Notify asynchronous caller */ |
251 | request = g_list_nth_data (priv->connect_requests, 0); |
252 | if (request) |
253 | { |
254 | - request->complete = TRUE; |
255 | + request_complete (request, G_OBJECT (greeter)); |
256 | priv->connect_requests = g_list_remove (priv->connect_requests, request); |
257 | g_object_unref (request); |
258 | } |
259 | @@ -501,11 +531,12 @@ |
260 | LightDMGreeterPrivate *priv = GET_PRIVATE (greeter); |
261 | Request *request; |
262 | |
263 | + /* Notify asynchronous caller */ |
264 | request = g_list_nth_data (priv->start_session_requests, 0); |
265 | if (request) |
266 | { |
267 | request->return_code = read_int (message, message_length, offset); |
268 | - request->complete = TRUE; |
269 | + request_complete (request, G_OBJECT (greeter)); |
270 | priv->start_session_requests = g_list_remove (priv->start_session_requests, request); |
271 | g_object_unref (request); |
272 | } |
273 | @@ -517,6 +548,7 @@ |
274 | LightDMGreeterPrivate *priv = GET_PRIVATE (greeter); |
275 | Request *request; |
276 | |
277 | + /* Notify asynchronous caller */ |
278 | request = g_list_nth_data (priv->ensure_shared_data_dir_requests, 0); |
279 | if (request) |
280 | { |
281 | @@ -527,7 +559,7 @@ |
282 | g_free (request->dir); |
283 | request->dir = NULL; |
284 | } |
285 | - request->complete = TRUE; |
286 | + request_complete (request, G_OBJECT (greeter)); |
287 | priv->ensure_shared_data_dir_requests = g_list_remove (priv->ensure_shared_data_dir_requests, request); |
288 | g_object_unref (request); |
289 | } |
290 | @@ -571,13 +603,16 @@ |
291 | } |
292 | |
293 | static guint8 * |
294 | -read_message (LightDMGreeter *greeter, gsize *length, gboolean block) |
295 | +recv_message (LightDMGreeter *greeter, gsize *length, gboolean block) |
296 | { |
297 | LightDMGreeterPrivate *priv = GET_PRIVATE (greeter); |
298 | gsize n_to_read, n_read; |
299 | guint8 *buffer; |
300 | GError *error = NULL; |
301 | |
302 | + if (!priv->from_server_channel) |
303 | + return NULL; |
304 | + |
305 | /* Read the header, or the whole message if we already have that */ |
306 | n_to_read = HEADER_SIZE; |
307 | if (priv->n_read >= HEADER_SIZE) |
308 | @@ -613,7 +648,7 @@ |
309 | if (n_to_read > 0) |
310 | { |
311 | priv->read_buffer = g_realloc (priv->read_buffer, HEADER_SIZE + n_to_read); |
312 | - return read_message (greeter, length, block); |
313 | + return recv_message (greeter, length, block); |
314 | } |
315 | } |
316 | |
317 | @@ -634,7 +669,7 @@ |
318 | gsize message_length; |
319 | |
320 | /* Read one message and process it */ |
321 | - message = read_message (greeter, &message_length, FALSE); |
322 | + message = recv_message (greeter, &message_length, FALSE); |
323 | if (message) |
324 | { |
325 | handle_message (greeter, message, message_length); |
326 | @@ -644,7 +679,7 @@ |
327 | return TRUE; |
328 | } |
329 | |
330 | -static void |
331 | +static gboolean |
332 | send_connect (LightDMGreeter *greeter, gboolean resettable) |
333 | { |
334 | guint8 message[MAX_MESSAGE_LENGTH]; |
335 | @@ -654,10 +689,11 @@ |
336 | write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CONNECT, string_length (VERSION) + int_length (), &offset); |
337 | write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset); |
338 | write_int (message, MAX_MESSAGE_LENGTH, resettable ? 1 : 0, &offset); |
339 | - write_message (greeter, message, offset); |
340 | + |
341 | + return send_message (greeter, message, offset); |
342 | } |
343 | |
344 | -static void |
345 | +static gboolean |
346 | send_start_session (LightDMGreeter *greeter, const gchar *session) |
347 | { |
348 | guint8 message[MAX_MESSAGE_LENGTH]; |
349 | @@ -670,10 +706,10 @@ |
350 | |
351 | write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset); |
352 | write_string (message, MAX_MESSAGE_LENGTH, session, &offset); |
353 | - write_message (greeter, message, offset); |
354 | + return send_message (greeter, message, offset); |
355 | } |
356 | |
357 | -static void |
358 | +static gboolean |
359 | send_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username) |
360 | { |
361 | guint8 message[MAX_MESSAGE_LENGTH]; |
362 | @@ -683,7 +719,51 @@ |
363 | |
364 | write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_ENSURE_SHARED_DIR, string_length (username), &offset); |
365 | write_string (message, MAX_MESSAGE_LENGTH, username, &offset); |
366 | - write_message (greeter, message, offset); |
367 | + return send_message (greeter, message, offset); |
368 | +} |
369 | + |
370 | +/** |
371 | + * lightdm_greeter_connect: |
372 | + * @greeter: The greeter to connect |
373 | + * @cancellable: (allow-none): A #GCancellable or %NULL. |
374 | + * @callback: (allow-none): A #GAsyncReadyCallback to call when completed or %NULL. |
375 | + * @user_data: (allow-none): data to pass to the @callback or %NULL. |
376 | + * |
377 | + * Asynchronously connects the greeter to the display manager. |
378 | + * |
379 | + * When the operation is finished, @callback will be invoked. You can then call lightdm_greeter_connect_finish() to get the result of the operation. |
380 | + * |
381 | + * See lightdm_greeter_connect_sync() for the synchronous version. |
382 | + **/ |
383 | +void |
384 | +lightdm_greeter_connect (LightDMGreeter *greeter, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) |
385 | +{ |
386 | + LightDMGreeterPrivate *priv; |
387 | + Request *request; |
388 | + |
389 | + g_return_if_fail (LIGHTDM_IS_GREETER (greeter)); |
390 | + |
391 | + priv = GET_PRIVATE (greeter); |
392 | + |
393 | + request = request_new (cancellable, callback, user_data); |
394 | + priv->connect_requests = g_list_append (priv->connect_requests, request); |
395 | + send_connect (greeter, priv->resettable); |
396 | +} |
397 | + |
398 | +/** |
399 | + * lightdm_greeter_connect_finish: |
400 | + * @result: A #GAsyncResult. |
401 | + * @error: return location for a #GError, or %NULL |
402 | + * |
403 | + * Finishes an operation started with lightdm_greeter_connect(). |
404 | + * |
405 | + * Return value: #TRUE if successfully connected |
406 | + **/ |
407 | +gboolean |
408 | +lightdm_greeter_connect_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error) |
409 | +{ |
410 | + g_return_if_fail (LIGHTDM_IS_GREETER (greeter)); |
411 | + return REQUEST (result)->complete; |
412 | } |
413 | |
414 | /** |
415 | @@ -699,42 +779,22 @@ |
416 | lightdm_greeter_connect_sync (LightDMGreeter *greeter, GError **error) |
417 | { |
418 | LightDMGreeterPrivate *priv; |
419 | - const gchar *fd; |
420 | Request *request; |
421 | |
422 | g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE); |
423 | |
424 | priv = GET_PRIVATE (greeter); |
425 | |
426 | - fd = g_getenv ("LIGHTDM_TO_SERVER_FD"); |
427 | - if (!fd) |
428 | - { |
429 | - g_warning ("No LIGHTDM_TO_SERVER_FD environment variable"); |
430 | - return FALSE; |
431 | - } |
432 | - priv->to_server_channel = g_io_channel_unix_new (atoi (fd)); |
433 | - g_io_channel_set_encoding (priv->to_server_channel, NULL, NULL); |
434 | - |
435 | - fd = g_getenv ("LIGHTDM_FROM_SERVER_FD"); |
436 | - if (!fd) |
437 | - { |
438 | - g_warning ("No LIGHTDM_FROM_SERVER_FD environment variable"); |
439 | - return FALSE; |
440 | - } |
441 | - priv->from_server_channel = g_io_channel_unix_new (atoi (fd)); |
442 | - g_io_channel_set_encoding (priv->from_server_channel, NULL, NULL); |
443 | - g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter); |
444 | - |
445 | /* Read until we are connected */ |
446 | send_connect (greeter, priv->resettable); |
447 | - request = request_new (); |
448 | + request = request_new (NULL, NULL, NULL); |
449 | priv->connect_requests = g_list_append (priv->connect_requests, g_object_ref (request)); |
450 | do |
451 | { |
452 | guint8 *message; |
453 | gsize message_length; |
454 | |
455 | - message = read_message (greeter, &message_length, TRUE); |
456 | + message = recv_message (greeter, &message_length, TRUE); |
457 | if (!message) |
458 | break; |
459 | handle_message (greeter, message, message_length); |
460 | @@ -1028,7 +1088,7 @@ |
461 | write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE, int_length () + string_length (username), &offset); |
462 | write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset); |
463 | write_string (message, MAX_MESSAGE_LENGTH, username, &offset); |
464 | - write_message (greeter, message, offset); |
465 | + send_message (greeter, message, offset); |
466 | } |
467 | |
468 | /** |
469 | @@ -1060,7 +1120,7 @@ |
470 | g_debug ("Starting authentication for guest account..."); |
471 | write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_AUTHENTICATE_AS_GUEST, int_length (), &offset); |
472 | write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset); |
473 | - write_message (greeter, message, offset); |
474 | + send_message (greeter, message, offset); |
475 | } |
476 | |
477 | /** |
478 | @@ -1117,7 +1177,7 @@ |
479 | write_int (message, MAX_MESSAGE_LENGTH, priv->authenticate_sequence_number, &offset); |
480 | write_string (message, MAX_MESSAGE_LENGTH, session, &offset); |
481 | write_string (message, MAX_MESSAGE_LENGTH, username, &offset); |
482 | - write_message (greeter, message, offset); |
483 | + send_message (greeter, message, offset); |
484 | } |
485 | |
486 | /** |
487 | @@ -1160,7 +1220,7 @@ |
488 | write_int (message, MAX_MESSAGE_LENGTH, g_list_length (priv->responses_received), &offset); |
489 | for (iter = priv->responses_received; iter; iter = iter->next) |
490 | write_string (message, MAX_MESSAGE_LENGTH, (gchar *)iter->data, &offset); |
491 | - write_message (greeter, message, offset); |
492 | + send_message (greeter, message, offset); |
493 | |
494 | g_list_free_full (priv->responses_received, g_free); |
495 | priv->responses_received = NULL; |
496 | @@ -1188,7 +1248,7 @@ |
497 | |
498 | priv->cancelling_authentication = TRUE; |
499 | write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_CANCEL_AUTHENTICATION, 0, &offset); |
500 | - write_message (greeter, message, offset); |
501 | + send_message (greeter, message, offset); |
502 | } |
503 | |
504 | /** |
505 | @@ -1258,7 +1318,53 @@ |
506 | |
507 | write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_SET_LANGUAGE, string_length (language), &offset); |
508 | write_string (message, MAX_MESSAGE_LENGTH, language, &offset); |
509 | - write_message (greeter, message, offset); |
510 | + send_message (greeter, message, offset); |
511 | +} |
512 | + |
513 | +/** |
514 | + * lightdm_greeter_start_session: |
515 | + * @greeter: A #LightDMGreeter |
516 | + * @session: (allow-none): The session to log into or #NULL to use the default. |
517 | + * @cancellable: (allow-none): A #GCancellable or %NULL. |
518 | + * @callback: (allow-none): A #GAsyncReadyCallback to call when completed or %NULL. |
519 | + * @user_data: (allow-none): data to pass to the @callback or %NULL. |
520 | + * |
521 | + * Asynchronously start a session for the authenticated user. |
522 | + * |
523 | + * When the operation is finished, @callback will be invoked. You can then call lightdm_greeter_start_session_finish() to get the result of the operation. |
524 | + * |
525 | + * See lightdm_greeter_start_session_sync() for the synchronous version. |
526 | + **/ |
527 | +void |
528 | +lightdm_greeter_start_session (LightDMGreeter *greeter, const gchar *session, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) |
529 | +{ |
530 | + LightDMGreeterPrivate *priv; |
531 | + Request *request; |
532 | + |
533 | + g_return_if_fail (LIGHTDM_IS_GREETER (greeter)); |
534 | + |
535 | + priv = GET_PRIVATE (greeter); |
536 | + |
537 | + send_start_session (greeter, session); |
538 | + request = request_new (cancellable, callback, user_data); |
539 | + priv->start_session_requests = g_list_append (priv->start_session_requests, request); |
540 | +} |
541 | + |
542 | +/** |
543 | + * lightdm_greeter_start_session_finish: |
544 | + * @greeter: A #LightDMGreeter |
545 | + * @result: A #GAsyncResult. |
546 | + * @error: return location for a #GError, or %NULL |
547 | + * |
548 | + * Start a session for the authenticated user. |
549 | + * |
550 | + * Return value: TRUE if the session was started. |
551 | + **/ |
552 | +gboolean |
553 | +lightdm_greeter_start_session_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error) |
554 | +{ |
555 | + g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE); |
556 | + return REQUEST (result)->return_code == 0; |
557 | } |
558 | |
559 | /** |
560 | @@ -1287,14 +1393,14 @@ |
561 | |
562 | /* Read until the session is started */ |
563 | send_start_session (greeter, session); |
564 | - request = request_new (); |
565 | + request = request_new (NULL, NULL, NULL); |
566 | priv->start_session_requests = g_list_append (priv->start_session_requests, g_object_ref (request)); |
567 | do |
568 | { |
569 | guint8 *message; |
570 | gsize message_length; |
571 | |
572 | - message = read_message (greeter, &message_length, TRUE); |
573 | + message = recv_message (greeter, &message_length, TRUE); |
574 | if (!message) |
575 | break; |
576 | handle_message (greeter, message, message_length); |
577 | @@ -1308,6 +1414,55 @@ |
578 | } |
579 | |
580 | /** |
581 | + * lightdm_greeter_ensure_shared_data_dir: |
582 | + * @greeter: A #LightDMGreeter |
583 | + * @username: A username |
584 | + * @cancellable: (allow-none): A #GCancellable or %NULL. |
585 | + * @callback: (allow-none): A #GAsyncReadyCallback to call when completed or %NULL. |
586 | + * @user_data: (allow-none): data to pass to the @callback or %NULL. |
587 | + * |
588 | + * Ensure that a shared data dir for the given user is available. Both the |
589 | + * greeter user and @username will have write access to that folder. The |
590 | + * intention is that larger pieces of shared data would be stored there (files |
591 | + * that the greeter creates but wants to give to a user -- like camera |
592 | + * photos -- or files that the user creates but wants the greeter to |
593 | + * see -- like contact avatars). |
594 | + * |
595 | + * LightDM will automatically create these if the user actually logs in, so |
596 | + * greeters only need to call this method if they want to store something in |
597 | + * the directory themselves. |
598 | + **/ |
599 | +void |
600 | +lightdm_greeter_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) |
601 | +{ |
602 | + LightDMGreeterPrivate *priv; |
603 | + Request *request; |
604 | + |
605 | + g_return_if_fail (LIGHTDM_IS_GREETER (greeter)); |
606 | + |
607 | + priv = GET_PRIVATE (greeter); |
608 | + |
609 | + send_ensure_shared_data_dir (greeter, username); |
610 | + request = request_new (cancellable, callback, user_data); |
611 | + priv->ensure_shared_data_dir_requests = g_list_append (priv->ensure_shared_data_dir_requests, request); |
612 | +} |
613 | + |
614 | +/** |
615 | + * lightdm_greeter_ensure_shared_data_dir_finish: |
616 | + * @result: A #GAsyncResult. |
617 | + * @greeter: A #LightDMGreeter |
618 | + * |
619 | + * |
620 | + * Return value: The path to the shared directory, free with g_free. |
621 | + **/ |
622 | +gchar * |
623 | +lightdm_greeter_ensure_shared_data_dir_finish (LightDMGreeter *greeter, GAsyncResult *result) |
624 | +{ |
625 | + g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), NULL); |
626 | + return g_strdup (REQUEST (result)->dir); |
627 | +} |
628 | + |
629 | +/** |
630 | * lightdm_greeter_ensure_shared_data_dir_sync: |
631 | * @greeter: A #LightDMGreeter |
632 | * @username: A username |
633 | @@ -1323,7 +1478,7 @@ |
634 | * greeters only need to call this method if they want to store something in |
635 | * the directory themselves. |
636 | * |
637 | - * Return value: The path to the shared directory, free with g_free |
638 | + * Return value: The path to the shared directory, free with g_free. |
639 | **/ |
640 | gchar * |
641 | lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username) |
642 | @@ -1340,14 +1495,14 @@ |
643 | |
644 | /* Read until a response */ |
645 | send_ensure_shared_data_dir (greeter, username); |
646 | - request = request_new (); |
647 | + request = request_new (NULL, NULL, NULL); |
648 | priv->ensure_shared_data_dir_requests = g_list_append (priv->ensure_shared_data_dir_requests, g_object_ref (request)); |
649 | do |
650 | { |
651 | guint8 *message; |
652 | gsize message_length; |
653 | |
654 | - message = read_message (greeter, &message_length, TRUE); |
655 | + message = recv_message (greeter, &message_length, TRUE); |
656 | if (!message) |
657 | break; |
658 | handle_message (greeter, message, message_length); |
659 | @@ -1364,9 +1519,29 @@ |
660 | lightdm_greeter_init (LightDMGreeter *greeter) |
661 | { |
662 | LightDMGreeterPrivate *priv = GET_PRIVATE (greeter); |
663 | + const gchar *fd; |
664 | |
665 | priv->read_buffer = g_malloc (HEADER_SIZE); |
666 | priv->hints = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); |
667 | + |
668 | + fd = g_getenv ("LIGHTDM_TO_SERVER_FD"); |
669 | + if (fd) |
670 | + { |
671 | + priv->to_server_channel = g_io_channel_unix_new (atoi (fd)); |
672 | + g_io_channel_set_encoding (priv->to_server_channel, NULL, NULL); |
673 | + } |
674 | + else |
675 | + g_warning ("No LIGHTDM_TO_SERVER_FD environment variable"); |
676 | + |
677 | + fd = g_getenv ("LIGHTDM_FROM_SERVER_FD"); |
678 | + if (fd) |
679 | + { |
680 | + priv->from_server_channel = g_io_channel_unix_new (atoi (fd)); |
681 | + g_io_channel_set_encoding (priv->from_server_channel, NULL, NULL); |
682 | + g_io_add_watch (priv->from_server_channel, G_IO_IN, from_server_cb, greeter); |
683 | + } |
684 | + else |
685 | + g_warning ("No LIGHTDM_FROM_SERVER_FD environment variable"); |
686 | } |
687 | |
688 | static void |
689 | @@ -1699,6 +1874,8 @@ |
690 | Request *request = REQUEST (object); |
691 | |
692 | g_free (request->dir); |
693 | + if (request->cancellable) |
694 | + g_object_unref (request->cancellable); |
695 | |
696 | G_OBJECT_CLASS (request_parent_class)->finalize (object); |
697 | } |
698 | @@ -1709,3 +1886,29 @@ |
699 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |
700 | object_class->finalize = request_finalize; |
701 | } |
702 | + |
703 | +static gpointer |
704 | +request_get_user_data (GAsyncResult *result) |
705 | +{ |
706 | + return REQUEST (result)->user_data; |
707 | +} |
708 | + |
709 | +static GObject * |
710 | +request_get_source_object (GAsyncResult *res) |
711 | +{ |
712 | + return NULL; |
713 | +} |
714 | + |
715 | +static gboolean |
716 | +request_is_tagged (GAsyncResult *res, gpointer source_tag) |
717 | +{ |
718 | + return FALSE; |
719 | +} |
720 | + |
721 | +static void |
722 | +request_iface_init (GAsyncResultIface *iface) |
723 | +{ |
724 | + iface->get_user_data = request_get_user_data; |
725 | + iface->get_source_object = request_get_source_object; |
726 | + iface->is_tagged = request_is_tagged; |
727 | +} |
728 | |
729 | === modified file 'liblightdm-gobject/liblightdm-gobject-1.vapi' |
730 | --- liblightdm-gobject/liblightdm-gobject-1.vapi 2014-04-08 00:32:13 +0000 |
731 | +++ liblightdm-gobject/liblightdm-gobject-1.vapi 2014-04-29 01:26:07 +0000 |
732 | @@ -24,6 +24,7 @@ |
733 | public signal void authentication_complete (); |
734 | public signal void autologin_timer_expired (); |
735 | |
736 | + public async bool connect_sync () throws GLib.Error; |
737 | public bool connect_sync () throws GLib.Error; |
738 | public unowned string get_hint (string name); |
739 | public unowned string default_session_hint { get; } |
740 | @@ -47,7 +48,10 @@ |
741 | public bool in_authentication { get; } |
742 | public bool is_authenticated { get; } |
743 | public unowned string? authentication_user { get; } |
744 | + public async void start_session (string? session = null) throws GLib.Error; |
745 | public bool start_session_sync (string? session = null) throws GLib.Error; |
746 | + public async string ensure_shared_data_dir (string username); |
747 | + public string ensure_shared_data_dir_sync (string username); |
748 | } |
749 | [CCode (has_type_id = false)] |
750 | public enum MessageType { |
751 | |
752 | === modified file 'liblightdm-gobject/lightdm/greeter.h' |
753 | --- liblightdm-gobject/lightdm/greeter.h 2014-04-28 20:56:28 +0000 |
754 | +++ liblightdm-gobject/lightdm/greeter.h 2014-04-29 01:26:07 +0000 |
755 | @@ -12,11 +12,12 @@ |
756 | #define LIGHTDM_GREETER_H_ |
757 | |
758 | #include <glib-object.h> |
759 | +#include <gio/gio.h> |
760 | |
761 | G_BEGIN_DECLS |
762 | |
763 | #define LIGHTDM_TYPE_GREETER (lightdm_greeter_get_type()) |
764 | -#define LIGHTDM_GREETER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LIGHTDM_TYPE_GREETER, LightDMGreeter)); |
765 | +#define LIGHTDM_GREETER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LIGHTDM_TYPE_GREETER, LightDMGreeter)) |
766 | #define LIGHTDM_GREETER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LIGHTDM_TYPE_GREETER, LightDMGreeterClass)) |
767 | #define LIGHTDM_IS_GREETER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LIGHTDM_TYPE_GREETER)) |
768 | #define LIGHTDM_IS_GREETER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LIGHTDM_TYPE_GREETER)) |
769 | @@ -73,6 +74,10 @@ |
770 | |
771 | void lightdm_greeter_set_resettable (LightDMGreeter *greeter, gboolean resettable); |
772 | |
773 | +void lightdm_greeter_connect (LightDMGreeter *greeter, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); |
774 | + |
775 | +gboolean lightdm_greeter_connect_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error); |
776 | + |
777 | gboolean lightdm_greeter_connect_sync (LightDMGreeter *greeter, GError **error); |
778 | |
779 | const gchar *lightdm_greeter_get_hint (LightDMGreeter *greeter, const gchar *name); |
780 | @@ -121,8 +126,16 @@ |
781 | |
782 | void lightdm_greeter_set_language (LightDMGreeter *greeter, const gchar *language); |
783 | |
784 | +void lightdm_greeter_start_session (LightDMGreeter *greeter, const gchar *session, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); |
785 | + |
786 | +gboolean lightdm_greeter_start_session_finish (LightDMGreeter *greeter, GAsyncResult *result, GError **error); |
787 | + |
788 | gboolean lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *session, GError **error); |
789 | |
790 | +void lightdm_greeter_ensure_shared_data_dir (LightDMGreeter *greeter, const gchar *username, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); |
791 | + |
792 | +gchar *lightdm_greeter_ensure_shared_data_dir_finish (LightDMGreeter *greeter, GAsyncResult *result); |
793 | + |
794 | gchar *lightdm_greeter_ensure_shared_data_dir_sync (LightDMGreeter *greeter, const gchar *username); |
795 | |
796 | G_END_DECLS |
797 | |
798 | === modified file 'tests/src/test-gobject-greeter.c' |
799 | --- tests/src/test-gobject-greeter.c 2014-04-28 20:56:28 +0000 |
800 | +++ tests/src/test-gobject-greeter.c 2014-04-29 01:26:07 +0000 |
801 | @@ -10,6 +10,7 @@ |
802 | |
803 | #include "status.h" |
804 | |
805 | +static int exit_code = EXIT_SUCCESS; |
806 | static gchar *greeter_id; |
807 | static GMainLoop *loop; |
808 | static LightDMGreeter *greeter; |
809 | @@ -103,6 +104,70 @@ |
810 | } |
811 | |
812 | static void |
813 | +start_session_finished (GObject *object, GAsyncResult *result, gpointer data) |
814 | +{ |
815 | + LightDMGreeter *greeter = LIGHTDM_GREETER (object); |
816 | + GError *error = NULL; |
817 | + |
818 | + if (!lightdm_greeter_start_session_finish (greeter, result, &error)) |
819 | + status_notify ("%s SESSION-FAILED", greeter_id); |
820 | + g_clear_error (&error); |
821 | +} |
822 | + |
823 | +static void |
824 | +write_shared_data_finished (GObject *object, GAsyncResult *result, gpointer data) |
825 | +{ |
826 | + LightDMGreeter *greeter = LIGHTDM_GREETER (object); |
827 | + gchar *dir, *path, *test_data; |
828 | + FILE *f; |
829 | + |
830 | + dir = lightdm_greeter_ensure_shared_data_dir_finish (greeter, result); |
831 | + if (!dir) |
832 | + { |
833 | + status_notify ("%s WRITE-SHARED-DATA ERROR=NO_SHARED_DIR", greeter_id); |
834 | + return; |
835 | + } |
836 | + |
837 | + path = g_build_filename (dir, "data", NULL); |
838 | + test_data = data; |
839 | + if (!(f = fopen (path, "w")) || fprintf (f, "%s", test_data) < 0) |
840 | + status_notify ("%s WRITE-SHARED-DATA ERROR=%s", greeter_id, strerror (errno)); |
841 | + else |
842 | + status_notify ("%s WRITE-SHARED-DATA RESULT=TRUE", greeter_id); |
843 | + g_free (test_data); |
844 | + |
845 | + if (f) |
846 | + fclose (f); |
847 | + g_free (path); |
848 | + g_free (dir); |
849 | +} |
850 | + |
851 | +static void |
852 | +read_shared_data_finished (GObject *object, GAsyncResult *result, gpointer data) |
853 | +{ |
854 | + LightDMGreeter *greeter = LIGHTDM_GREETER (object); |
855 | + gchar *dir, *path; |
856 | + gchar *contents = NULL; |
857 | + GError *error = NULL; |
858 | + |
859 | + dir = lightdm_greeter_ensure_shared_data_dir_finish (greeter, result); |
860 | + if (!dir) |
861 | + { |
862 | + status_notify ("%s READ-SHARED-DATA ERROR=NO_SHARED_DIR", greeter_id); |
863 | + return; |
864 | + } |
865 | + |
866 | + path = g_build_filename (dir, "data", NULL); |
867 | + if (g_file_get_contents (path, &contents, NULL, &error)) |
868 | + status_notify ("%s READ-SHARED-DATA DATA=%s", greeter_id, contents); |
869 | + else |
870 | + status_notify ("%s READ-SHARED-DATA ERROR=%s", greeter_id, error->message); |
871 | + g_free (path); |
872 | + g_free (contents); |
873 | + g_clear_error (&error); |
874 | +} |
875 | + |
876 | +static void |
877 | request_cb (const gchar *name, GHashTable *params) |
878 | { |
879 | if (!name) |
880 | @@ -133,10 +198,7 @@ |
881 | lightdm_greeter_cancel_authentication (greeter); |
882 | |
883 | else if (strcmp (name, "START-SESSION") == 0) |
884 | - { |
885 | - if (!lightdm_greeter_start_session_sync (greeter, g_hash_table_lookup (params, "SESSION"), NULL)) |
886 | - status_notify ("%s SESSION-FAILED", greeter_id); |
887 | - } |
888 | + lightdm_greeter_start_session (greeter, g_hash_table_lookup (params, "SESSION"), NULL, start_session_finished, NULL); |
889 | |
890 | else if (strcmp (name, "LOG-DEFAULT-SESSION") == 0) |
891 | status_notify ("%s LOG-DEFAULT-SESSION SESSION=%s", greeter_id, lightdm_greeter_get_default_session_hint (greeter)); |
892 | @@ -146,56 +208,12 @@ |
893 | |
894 | else if (strcmp (name, "WRITE-SHARED-DATA") == 0) |
895 | { |
896 | - gchar *dir; |
897 | - |
898 | - dir = lightdm_greeter_ensure_shared_data_dir_sync (greeter, g_hash_table_lookup (params, "USERNAME")); |
899 | - if (dir) |
900 | - { |
901 | - gchar *path; |
902 | - FILE *f; |
903 | - |
904 | - g_printerr ("dir='%s'\n", dir); |
905 | - |
906 | - path = g_build_filename (dir, "data", NULL); |
907 | - if (!(f = fopen (path, "w")) || fprintf (f, "%s", (const gchar *) g_hash_table_lookup (params, "DATA")) < 0) |
908 | - status_notify ("%s WRITE-SHARED-DATA ERROR=%s", greeter_id, strerror (errno)); |
909 | - else |
910 | - status_notify ("%s WRITE-SHARED-DATA RESULT=TRUE", greeter_id); |
911 | - |
912 | - if (f) |
913 | - fclose (f); |
914 | - g_free (path); |
915 | - g_free (dir); |
916 | - } |
917 | - else |
918 | - status_notify ("%s WRITE-SHARED-DATA ERROR=NO_SHARED_DIR", greeter_id); |
919 | + const gchar *data = g_hash_table_lookup (params, "DATA"); |
920 | + lightdm_greeter_ensure_shared_data_dir (greeter, g_hash_table_lookup (params, "USERNAME"), NULL, write_shared_data_finished, g_strdup (data)); |
921 | } |
922 | |
923 | else if (strcmp (name, "READ-SHARED-DATA") == 0) |
924 | - { |
925 | - gchar *dir; |
926 | - |
927 | - dir = lightdm_greeter_ensure_shared_data_dir_sync (greeter, g_hash_table_lookup (params, "USERNAME")); |
928 | - if (dir) |
929 | - { |
930 | - gchar *path; |
931 | - gchar *contents = NULL; |
932 | - GError *error = NULL; |
933 | - |
934 | - g_printerr ("dir='%s'\n", dir); |
935 | - |
936 | - path = g_build_filename (dir, "data", NULL); |
937 | - if (g_file_get_contents (path, &contents, NULL, &error)) |
938 | - status_notify ("%s READ-SHARED-DATA DATA=%s", greeter_id, contents); |
939 | - else |
940 | - status_notify ("%s READ-SHARED-DATA ERROR=%s", greeter_id, error->message); |
941 | - g_free (path); |
942 | - g_free (contents); |
943 | - g_clear_error (&error); |
944 | - } |
945 | - else |
946 | - status_notify ("%s READ-SHARED-DATA ERROR=NO_SHARED_DIR", greeter_id); |
947 | - } |
948 | + lightdm_greeter_ensure_shared_data_dir (greeter, g_hash_table_lookup (params, "USERNAME"), NULL, read_shared_data_finished, NULL); |
949 | |
950 | else if (strcmp (name, "WATCH-USER") == 0) |
951 | { |
952 | @@ -350,6 +368,25 @@ |
953 | status_notify ("%s USER-REMOVED USERNAME=%s", greeter_id, lightdm_user_get_name (user)); |
954 | } |
955 | |
956 | +static void |
957 | +connect_finished (GObject *object, GAsyncResult *result, gpointer data) |
958 | +{ |
959 | + LightDMGreeter *greeter = LIGHTDM_GREETER (object); |
960 | + GError *error = NULL; |
961 | + |
962 | + if (!lightdm_greeter_connect_finish (greeter, result, &error)) |
963 | + { |
964 | + status_notify ("%s FAIL-CONNECT-DAEMON", greeter_id); |
965 | + exit_code = EXIT_FAILURE; |
966 | + g_main_loop_quit (loop); |
967 | + return; |
968 | + } |
969 | + |
970 | + status_notify ("%s CONNECTED-TO-DAEMON", greeter_id); |
971 | + |
972 | + notify_hints (greeter); |
973 | +} |
974 | + |
975 | int |
976 | main (int argc, char **argv) |
977 | { |
978 | @@ -444,17 +481,9 @@ |
979 | } |
980 | |
981 | status_notify ("%s CONNECT-TO-DAEMON", greeter_id); |
982 | - if (!lightdm_greeter_connect_sync (greeter, NULL)) |
983 | - { |
984 | - status_notify ("%s FAIL-CONNECT-DAEMON", greeter_id); |
985 | - return EXIT_FAILURE; |
986 | - } |
987 | - |
988 | - status_notify ("%s CONNECTED-TO-DAEMON", greeter_id); |
989 | - |
990 | - notify_hints (greeter); |
991 | + lightdm_greeter_connect (greeter, NULL, connect_finished, NULL); |
992 | |
993 | g_main_loop_run (loop); |
994 | |
995 | - return EXIT_SUCCESS; |
996 | + return exit_code; |
997 | } |
FAILED: Continuous integration, rev:1954 jenkins. qa.ubuntu. com/job/ lightdm- ci/284/ jenkins. qa.ubuntu. com/job/ lightdm- trusty- amd64-ci/ 78/console jenkins. qa.ubuntu. com/job/ lightdm- trusty- armhf-ci/ 78/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/lightdm- ci/284/ rebuild
http://