1 /*
2 * account-request.c - object for a currently non-existent account to create
3 *
4 * Copyright © 2012 Collabora Ltd. <http://www.collabora.co.uk/>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "config.h"
22
23 #include "telepathy-glib/account-request.h"
24
25 #include <telepathy-glib/gtypes.h>
26 #include <telepathy-glib/interfaces.h>
27 #include <telepathy-glib/util.h>
28 #include <telepathy-glib/simple-client-factory.h>
29
30 #define DEBUG_FLAG TP_DEBUG_ACCOUNTS
31 #include "telepathy-glib/dbus-internal.h"
32 #include "telepathy-glib/debug-internal.h"
33 #include "telepathy-glib/util-internal.h"
34 #include "telepathy-glib/variant-util-internal.h"
35
36 /**
37 * SECTION:account-request
38 * @title: TpAccountRequest
39 * @short_description: object for a currently non-existent account in
40 * order to create easily without speaking fluent D-Bus
41 * @see_also: #TpAccountManager
42 *
43 * This is a convenience object to aid in the creation of accounts on
44 * a #TpAccountManager without having to construct #GHashTables with
45 * well-known keys. For example:
46 *
47 * |[
48 * static void created_cb (GObject *object, GAsyncResult *res, gpointer user_data);
49 *
50 * static void
51 * create_acount (void)
52 * {
53 * TpAccountManager *am = tp_account_manager_dup ();
54 * TpAccountRequest *req;
55 *
56 * req = tp_account_request_new (am, "gabble", "jabber", "Work Jabber account");
57 *
58 * tp_account_request_set_parameter (req, "account", "walter.white@lospollos.lit");
59 *
60 * // ...
61 *
62 * tp_account_request_create_account_async (req, created_cb, NULL);
63 * g_object_unref (req);
64 * g_object_unref (am);
65 * }
66 *
67 * static void
68 * created_cb (GObject *object,
69 * GAsyncResult *result,
70 * gpointer user_data)
71 * {
72 * TpAccountRequest *req = TP_ACCOUNT_REQUEST (object);
73 * TpAccount *account;
74 * GError *error = NULL;
75 *
76 * account = tp_account_request_create_account_finish (req, result, &error);
77 *
78 * if (account == NULL)
79 * {
80 * g_error ("Failed to create account: %s\n", error->message);
81 * g_clear_error (&error);
82 * return;
83 * }
84 *
85 * // ...
86 *
87 * g_object_unref (account);
88 * }
89 * ]|
90 *
91 *
92 * Since: 0.19.1
93 */
94
95 /**
96 * TpAccountRequest:
97 *
98 * An object for representing a currently non-existent account which
99 * is to be created on a #TpAccountManager.
100 *
101 * Since: 0.19.1
102 */
103
104 /**
105 * TpAccountRequestClass:
106 *
107 * The class of a #TpAccountRequest.
108 */
109
110 struct _TpAccountRequestPrivate {
111 TpAccountManager *account_manager;
112
113 GSimpleAsyncResult *result;
114 gboolean created;
115
116 gchar *cm_name;
117 gchar *proto_name;
118 gchar *display_name;
119
120 GHashTable *parameters;
121 GHashTable *properties;
122 };
123
124 G_DEFINE_TYPE (TpAccountRequest, tp_account_request, G_TYPE_OBJECT)
125
126 /* properties */
127 enum {
128 PROP_ACCOUNT_MANAGER = 1,
129 PROP_CONNECTION_MANAGER,
130 PROP_PROTOCOL,
131 PROP_DISPLAY_NAME,
132 PROP_PARAMETERS,
133 PROP_PROPERTIES,
134 PROP_ICON_NAME,
135 PROP_NICKNAME,
136 PROP_REQUESTED_PRESENCE_TYPE,
137 PROP_REQUESTED_STATUS,
138 PROP_REQUESTED_STATUS_MESSAGE,
139 PROP_AUTOMATIC_PRESENCE_TYPE,
140 PROP_AUTOMATIC_STATUS,
141 PROP_AUTOMATIC_STATUS_MESSAGE,
142 PROP_ENABLED,
143 PROP_CONNECT_AUTOMATICALLY,
144 PROP_SUPERSEDES,
145 PROP_AVATAR,
146 PROP_AVATAR_MIME_TYPE,
147 PROP_SERVICE,
148 PROP_STORAGE_PROVIDER,
149 N_PROPS
150 };
151
152 static void
tp_account_request_init(TpAccountRequest * self)153 tp_account_request_init (TpAccountRequest *self)
154 {
155 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TYPE_ACCOUNT_REQUEST,
156 TpAccountRequestPrivate);
157 }
158
159 static void
tp_account_request_constructed(GObject * object)160 tp_account_request_constructed (GObject *object)
161 {
162 TpAccountRequest *self = TP_ACCOUNT_REQUEST (object);
163 TpAccountRequestPrivate *priv = self->priv;
164 void (*chain_up) (GObject *) =
165 ((GObjectClass *) tp_account_request_parent_class)->constructed;
166
167 if (chain_up != NULL)
168 chain_up (object);
169
170 g_assert (priv->account_manager != NULL);
171 g_assert (priv->cm_name != NULL);
172 g_assert (priv->proto_name != NULL);
173 g_assert (priv->display_name != NULL);
174
175 priv->parameters = g_hash_table_new_full (g_str_hash, g_str_equal,
176 g_free, (GDestroyNotify) tp_g_value_slice_free);
177
178 priv->properties = tp_asv_new (NULL, NULL);
179 }
180
181 #define GET_PRESENCE_VALUE(key, offset, type) \
182 G_STMT_START { \
183 GValueArray *_arr = tp_asv_get_boxed (self->priv->properties, \
184 key, TP_STRUCT_TYPE_SIMPLE_PRESENCE); \
185 if (_arr != NULL) \
186 g_value_set_##type (value, g_value_get_##type (_arr->values + offset)); \
187 } G_STMT_END
188
189 static void
tp_account_request_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)190 tp_account_request_get_property (GObject *object,
191 guint prop_id,
192 GValue *value,
193 GParamSpec *pspec)
194 {
195 TpAccountRequest *self = TP_ACCOUNT_REQUEST (object);
196
197 switch (prop_id)
198 {
199 case PROP_ACCOUNT_MANAGER:
200 g_value_set_object (value, self->priv->account_manager);
201 break;
202 case PROP_CONNECTION_MANAGER:
203 g_value_set_string (value, self->priv->cm_name);
204 break;
205 case PROP_PROTOCOL:
206 g_value_set_string (value, self->priv->proto_name);
207 break;
208 case PROP_DISPLAY_NAME:
209 g_value_set_string (value, self->priv->display_name);
210 break;
211 case PROP_PARAMETERS:
212 g_value_take_variant (value, _tp_asv_to_vardict (self->priv->parameters));
213 break;
214 case PROP_PROPERTIES:
215 g_value_take_variant (value, _tp_asv_to_vardict (self->priv->properties));
216 break;
217 case PROP_ICON_NAME:
218 g_value_set_string (value,
219 tp_asv_get_string (self->priv->properties,
220 TP_PROP_ACCOUNT_ICON));
221 break;
222 case PROP_NICKNAME:
223 g_value_set_string (value,
224 tp_asv_get_string (self->priv->properties,
225 TP_PROP_ACCOUNT_NICKNAME));
226 break;
227 case PROP_REQUESTED_PRESENCE_TYPE:
228 GET_PRESENCE_VALUE (TP_PROP_ACCOUNT_REQUESTED_PRESENCE, 0, uint);
229 break;
230 case PROP_REQUESTED_STATUS:
231 GET_PRESENCE_VALUE (TP_PROP_ACCOUNT_REQUESTED_PRESENCE, 1, string);
232 break;
233 case PROP_REQUESTED_STATUS_MESSAGE:
234 GET_PRESENCE_VALUE (TP_PROP_ACCOUNT_REQUESTED_PRESENCE, 2, string);
235 break;
236 case PROP_AUTOMATIC_PRESENCE_TYPE:
237 GET_PRESENCE_VALUE (TP_PROP_ACCOUNT_AUTOMATIC_PRESENCE, 0, uint);
238 break;
239 case PROP_AUTOMATIC_STATUS:
240 GET_PRESENCE_VALUE (TP_PROP_ACCOUNT_AUTOMATIC_PRESENCE, 1, string);
241 break;
242 case PROP_AUTOMATIC_STATUS_MESSAGE:
243 GET_PRESENCE_VALUE (TP_PROP_ACCOUNT_AUTOMATIC_PRESENCE, 2, string);
244 break;
245 case PROP_ENABLED:
246 g_value_set_boolean (value,
247 tp_asv_get_boolean (self->priv->properties,
248 TP_PROP_ACCOUNT_ENABLED, NULL));
249 break;
250 case PROP_CONNECT_AUTOMATICALLY:
251 g_value_set_boolean (value,
252 tp_asv_get_boolean (self->priv->properties,
253 TP_PROP_ACCOUNT_CONNECT_AUTOMATICALLY,
254 NULL));
255 break;
256 case PROP_SUPERSEDES:
257 {
258 GPtrArray *array = tp_asv_get_boxed (self->priv->properties,
259 TP_PROP_ACCOUNT_SUPERSEDES,
260 TP_ARRAY_TYPE_OBJECT_PATH_LIST);
261
262 if (array != NULL)
263 {
264 /* add the NULL-termination to make it a real GStrv */
265 g_ptr_array_add (array, NULL);
266 g_value_set_boxed (value, array->pdata);
267 g_ptr_array_remove_index (array, (array->len - 1));
268 }
269 else
270 {
271 g_value_set_boxed (value, NULL);
272 }
273 }
274 break;
275 case PROP_AVATAR:
276 {
277 GValueArray *array = tp_asv_get_boxed (self->priv->properties,
278 TP_PROP_ACCOUNT_INTERFACE_AVATAR_AVATAR,
279 TP_STRUCT_TYPE_AVATAR);
280
281 if (array != NULL)
282 g_value_set_boxed (value, g_value_get_boxed (array->values));
283 }
284 break;
285 case PROP_AVATAR_MIME_TYPE:
286 {
287 GValueArray *array = tp_asv_get_boxed (self->priv->properties,
288 TP_PROP_ACCOUNT_INTERFACE_AVATAR_AVATAR,
289 TP_STRUCT_TYPE_AVATAR);
290
291 if (array != NULL)
292 g_value_set_string (value, g_value_get_string (array->values + 1));
293 }
294 break;
295 case PROP_SERVICE:
296 g_value_set_string (value, tp_asv_get_string (self->priv->properties,
297 TP_PROP_ACCOUNT_SERVICE));
298 break;
299 case PROP_STORAGE_PROVIDER:
300 g_value_set_string (value, tp_asv_get_string (self->priv->properties,
301 TP_PROP_ACCOUNT_INTERFACE_STORAGE_STORAGE_PROVIDER));
302 break;
303 default:
304 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
305 break;
306 }
307 }
308
309 #undef GET_PRESENCE_VALUE
310
311 static void
tp_account_request_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)312 tp_account_request_set_property (GObject *object,
313 guint property_id,
314 const GValue *value,
315 GParamSpec *pspec)
316 {
317 TpAccountRequest *self = TP_ACCOUNT_REQUEST (object);
318 TpAccountRequestPrivate *priv = self->priv;
319
320 switch (property_id)
321 {
322 case PROP_ACCOUNT_MANAGER:
323 g_assert (priv->account_manager == NULL);
324 priv->account_manager = g_value_dup_object (value);
325 break;
326 case PROP_CONNECTION_MANAGER:
327 g_assert (priv->cm_name == NULL);
328 priv->cm_name = g_value_dup_string (value);
329 break;
330 case PROP_PROTOCOL:
331 g_assert (priv->proto_name == NULL);
332 priv->proto_name = g_value_dup_string (value);
333 break;
334 case PROP_DISPLAY_NAME:
335 g_assert (priv->display_name == NULL);
336 priv->display_name = g_value_dup_string (value);
337 break;
338 default:
339 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
340 break;
341 }
342 }
343
344 static void
tp_account_request_dispose(GObject * object)345 tp_account_request_dispose (GObject *object)
346 {
347 TpAccountRequest *self = TP_ACCOUNT_REQUEST (object);
348 TpAccountRequestPrivate *priv = self->priv;
349
350 g_clear_object (&priv->account_manager);
351
352 tp_clear_pointer (&priv->parameters, g_hash_table_unref);
353 tp_clear_pointer (&priv->properties, g_hash_table_unref);
354
355 /* release any references held by the object here */
356
357 if (G_OBJECT_CLASS (tp_account_request_parent_class)->dispose != NULL)
358 G_OBJECT_CLASS (tp_account_request_parent_class)->dispose (object);
359 }
360
361 static void
tp_account_request_finalize(GObject * object)362 tp_account_request_finalize (GObject *object)
363 {
364 TpAccountRequest *self = TP_ACCOUNT_REQUEST (object);
365 TpAccountRequestPrivate *priv = self->priv;
366
367 tp_clear_pointer (&priv->cm_name, g_free);
368 tp_clear_pointer (&priv->proto_name, g_free);
369 tp_clear_pointer (&priv->display_name, g_free);
370
371 /* free any data held directly by the object here */
372
373 if (G_OBJECT_CLASS (tp_account_request_parent_class)->finalize != NULL)
374 G_OBJECT_CLASS (tp_account_request_parent_class)->finalize (object);
375 }
376
377 static void
tp_account_request_class_init(TpAccountRequestClass * klass)378 tp_account_request_class_init (TpAccountRequestClass *klass)
379 {
380 GObjectClass *object_class = (GObjectClass *) klass;
381
382 g_type_class_add_private (klass, sizeof (TpAccountRequestPrivate));
383
384 object_class->constructed = tp_account_request_constructed;
385 object_class->get_property = tp_account_request_get_property;
386 object_class->set_property = tp_account_request_set_property;
387 object_class->dispose = tp_account_request_dispose;
388 object_class->finalize = tp_account_request_finalize;
389
390 /**
391 * TpAccountRequest:account-manager:
392 *
393 * The #TpAccountManager to create the account on.
394 *
395 * Since: 0.19.1
396 */
397 g_object_class_install_property (object_class, PROP_ACCOUNT_MANAGER,
398 g_param_spec_object ("account-manager",
399 "Account manager",
400 "The account's account manager",
401 TP_TYPE_ACCOUNT_MANAGER,
402 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
403
404 /**
405 * TpAccountRequest:connection-manager:
406 *
407 * The account's connection manager name.
408 *
409 * Since: 0.19.1
410 */
411 g_object_class_install_property (object_class, PROP_CONNECTION_MANAGER,
412 g_param_spec_string ("connection-manager",
413 "Connection manager",
414 "The account's connection manager name",
415 NULL,
416 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
417
418 /**
419 * TpAccountRequest:protocol:
420 *
421 * The account's machine-readable protocol name, such as "jabber", "msn" or
422 * "local-xmpp". Recommended names for most protocols can be found in the
423 * Telepathy D-Bus Interface Specification.
424 *
425 * Since: 0.19.1
426 */
427 g_object_class_install_property (object_class, PROP_PROTOCOL,
428 g_param_spec_string ("protocol",
429 "Protocol",
430 "The account's protocol name",
431 NULL,
432 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
433
434 /**
435 * TpAccountRequest:display-name:
436 *
437 * The account's display name. To change this property use
438 * tp_account_request_set_display_name().
439 *
440 * Since: 0.19.1
441 */
442 g_object_class_install_property (object_class, PROP_DISPLAY_NAME,
443 g_param_spec_string ("display-name",
444 "DisplayName",
445 "The account's display name",
446 NULL,
447 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
448
449 /**
450 * TpAccountRequest:parameters:
451 *
452 * The account's connection parameters. To add a parameter, use
453 * tp_account_request_set_parameter() or another convience function.
454 *
455 * Since: 0.19.1
456 */
457 g_object_class_install_property (object_class, PROP_PARAMETERS,
458 g_param_spec_variant ("parameters",
459 "Parameters",
460 "Connection parameters of the account",
461 G_VARIANT_TYPE_VARDICT, NULL,
462 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
463
464 /**
465 * TpAccountRequest:properties:
466 *
467 * The account's properties.
468 *
469 * Since: 0.19.1
470 */
471 g_object_class_install_property (object_class, PROP_PROPERTIES,
472 g_param_spec_variant ("properties",
473 "Properties",
474 "Account properties",
475 G_VARIANT_TYPE_VARDICT, NULL,
476 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
477
478 /**
479 * TpAccountRequest:icon-name:
480 *
481 * The account's icon name. To change this propery, use
482 * tp_account_request_set_icon_name().
483 *
484 * Since: 0.19.1
485 */
486 g_object_class_install_property (object_class, PROP_ICON_NAME,
487 g_param_spec_string ("icon-name",
488 "Icon",
489 "The account's icon name",
490 NULL,
491 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
492
493 /**
494 * TpAccountRequest:nickname:
495 *
496 * The account's nickname. To change this property use
497 * tp_account_request_set_nickname().
498 *
499 * Since: 0.19.1
500 */
501 g_object_class_install_property (object_class, PROP_NICKNAME,
502 g_param_spec_string ("nickname",
503 "Nickname",
504 "The account's nickname",
505 NULL,
506 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
507
508 /**
509 * TpAccountRequest:requested-presence-type:
510 *
511 * The account's requested presence type (a
512 * #TpConnectionPresenceType). To change this property use
513 * tp_account_request_set_requested_presence().
514 *
515 * Since: 0.19.1
516 */
517 g_object_class_install_property (object_class, PROP_REQUESTED_PRESENCE_TYPE,
518 g_param_spec_uint ("requested-presence-type",
519 "RequestedPresence",
520 "The account's requested presence type",
521 0,
522 TP_NUM_CONNECTION_PRESENCE_TYPES,
523 TP_CONNECTION_PRESENCE_TYPE_UNSET,
524 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
525
526 /**
527 * TpAccountRequest:requested-status:
528 *
529 * The requested Status string of the account. To change this
530 * property use tp_account_request_set_requested_presence().
531 *
532 * Since: 0.19.1
533 */
534 g_object_class_install_property (object_class, PROP_REQUESTED_STATUS,
535 g_param_spec_string ("requested-status",
536 "RequestedStatus",
537 "The account's requested status string",
538 NULL,
539 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
540
541 /**
542 * TpAccountRequest:requested-status-message:
543 *
544 * The requested status message message of the account. To change
545 * this property use tp_account_request_set_requested_presence().
546 *
547 * Since: 0.19.1
548 */
549 g_object_class_install_property (object_class, PROP_REQUESTED_STATUS_MESSAGE,
550 g_param_spec_string ("requested-status-message",
551 "RequestedStatusMessage",
552 "The requested Status message string of the account",
553 NULL,
554 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
555
556 /**
557 * TpAccountRequest:automatic-presence-type:
558 *
559 * The account's automatic presence type (a
560 * #TpConnectionPresenceType). To change this property use
561 * tp_account_request_set_automatic_presence().
562 *
563 * When the account is put online automatically, for instance to
564 * make a channel request or because network connectivity becomes
565 * available, the automatic presence type, status and message will
566 * be copied to their "requested" counterparts.
567 *
568 * Since: 0.19.1
569 */
570 g_object_class_install_property (object_class, PROP_AUTOMATIC_PRESENCE_TYPE,
571 g_param_spec_uint ("automatic-presence-type",
572 "AutomaticPresence type",
573 "Presence type used to put the account online automatically",
574 0,
575 TP_NUM_CONNECTION_PRESENCE_TYPES,
576 TP_CONNECTION_PRESENCE_TYPE_UNSET,
577 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
578
579 /**
580 * TpAccountRequest:automatic-status:
581 *
582 * The string status name to use in conjunction with the
583 * #TpAccountRequest:automatic-presence-type. To change this property
584 * use tp_account_request_set_automatic_presence().
585 *
586 * Since: 0.19.1
587 */
588 g_object_class_install_property (object_class, PROP_AUTOMATIC_STATUS,
589 g_param_spec_string ("automatic-status",
590 "AutomaticPresence status",
591 "Presence status used to put the account online automatically",
592 NULL,
593 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
594
595 /**
596 * TpAccountRequest:automatic-status-message:
597 *
598 * The user-defined message to use in conjunction with the
599 * #TpAccount:automatic-presence-type. To change this property use
600 * tp_account_request_set_automatic_presence().
601 *
602 * Since: 0.19.1
603 */
604 g_object_class_install_property (object_class, PROP_AUTOMATIC_STATUS_MESSAGE,
605 g_param_spec_string ("automatic-status-message",
606 "AutomaticPresence message",
607 "User-defined message used to put the account online automatically",
608 NULL,
609 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
610
611 /**
612 * TpAccountRequest:enabled:
613 *
614 * Whether the account is enabled or not. To change this property
615 * use tp_account_request_set_enabled().
616 *
617 * Since: 0.19.1
618 */
619 g_object_class_install_property (object_class, PROP_ENABLED,
620 g_param_spec_boolean ("enabled",
621 "Enabled",
622 "Whether this account is enabled or not",
623 FALSE,
624 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
625
626 /**
627 * TpAccountRequest:connect-automatically:
628 *
629 * Whether the account should connect automatically or not. To change this
630 * property, use tp_account_request_set_connect_automatically().
631 *
632 * Since: 0.19.1
633 */
634 g_object_class_install_property (object_class, PROP_CONNECT_AUTOMATICALLY,
635 g_param_spec_boolean ("connect-automatically",
636 "ConnectAutomatically",
637 "Whether this account should connect automatically or not",
638 FALSE,
639 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
640
641 /**
642 * TpAccountRequest:supersedes:
643 *
644 * The object paths of previously-active accounts superseded by this one.
645 * For instance, this can be used in a logger to read old logs for an
646 * account that has been migrated from one connection manager to another.
647 *
648 * To add to this property use tp_account_request_add_supersedes().
649 *
650 * Since: 0.19.1
651 */
652 g_object_class_install_property (object_class, PROP_SUPERSEDES,
653 g_param_spec_boxed ("supersedes",
654 "Supersedes",
655 "Accounts superseded by this one",
656 G_TYPE_STRV,
657 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
658
659 /**
660 * TpAccountRequest:avatar:
661 *
662 * The avatar set on the account. The avatar's mime type can be read
663 * in the #TpAccountRequest:avatar-mime-type property. To change this
664 * property, use tp_account_request_set_avatar().
665 *
666 * Since: 0.19.1
667 */
668 g_object_class_install_property (object_class, PROP_AVATAR,
669 g_param_spec_boxed ("avatar",
670 "Avatar",
671 "The account's avatar data",
672 G_TYPE_ARRAY,
673 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
674
675 /**
676 * TpAccountRequest:avatar-mime-type:
677 *
678 * The mime type of the #TpAccountRequest:avatar property. To change
679 * this property, use tp_account_request_set_avatar().
680 *
681 * Since: 0.19.1
682 */
683 g_object_class_install_property (object_class, PROP_AVATAR_MIME_TYPE,
684 g_param_spec_string ("avatar-mime-type",
685 "Avatar mime type",
686 "The account's avatar's mime type",
687 NULL,
688 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
689
690 /**
691 * TpAccountRequest:service:
692 *
693 * A string describing the service of the account, which must
694 * consist only of ASCII letters, numbers and hyphen/minus signs,
695 * and start with a letter (matching the requirements for
696 * Protocol). To change this property, use
697 * tp_account_request_set_service().
698 *
699 * Since: 0.19.1
700 */
701 g_object_class_install_property (object_class, PROP_SERVICE,
702 g_param_spec_string ("service",
703 "Service",
704 "The account's service",
705 NULL,
706 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
707
708 /**
709 * TpAccountRequest:storage-provider:
710 *
711 * The account's storage provider. To change this property use
712 * tp_account_request_set_storage_provider().
713 *
714 * Since: 0.19.4
715 */
716 g_object_class_install_property (object_class, PROP_STORAGE_PROVIDER,
717 g_param_spec_string ("storage-provider",
718 "Storage Provider",
719 "The account's storage provider",
720 NULL,
721 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
722 }
723
724 /**
725 * tp_account_request_new:
726 * @account_manager: the #TpAccountManager to create the account on
727 * @manager: the name of the connection manager
728 * @protocol: the name of the protocol on @manager
729 * @display_name: the user-visible name of this account
730 *
731 * Convenience function to create a new account request object which
732 * will assist in the creation of a new account on @account_manager,
733 * using connection manager @manager, and protocol @protocol.
734 *
735 * Returns: (transfer full): a new reference to an account request
736 * object, or %NULL if any argument is incorrect
737 *
738 * Since: 0.19.1
739 */
740 TpAccountRequest *
tp_account_request_new(TpAccountManager * account_manager,const gchar * manager,const gchar * protocol,const gchar * display_name)741 tp_account_request_new (TpAccountManager *account_manager,
742 const gchar *manager,
743 const gchar *protocol,
744 const gchar *display_name)
745 {
746 g_return_val_if_fail (TP_IS_ACCOUNT_MANAGER (account_manager), NULL);
747 g_return_val_if_fail (manager != NULL, NULL);
748 g_return_val_if_fail (protocol != NULL, NULL);
749
750 return g_object_new (TP_TYPE_ACCOUNT_REQUEST,
751 "account-manager", account_manager,
752 "connection-manager", manager,
753 "protocol", protocol,
754 "display-name", display_name,
755 NULL);
756 }
757
758 /**
759 * tp_account_request_new_from_protocol:
760 * @account_manager: the #TpAccountManager to create the account on
761 * @protocol: a #TpProtocol
762 * @display_name: the user-visible name of this account
763 *
764 * Convenience function to create a new #TpAccountRequest object using
765 * a #TpProtocol instance, instead of specifying connection manager
766 * and protocol name specifically. See tp_account_request_new() for
767 * more details.
768 *
769 * Returns: (transfer full): a new reference to an account request
770 * object, or %NULL if any argument is incorrect
771 *
772 * Since: 0.19.1
773 */
774 TpAccountRequest *
tp_account_request_new_from_protocol(TpAccountManager * account_manager,TpProtocol * protocol,const gchar * display_name)775 tp_account_request_new_from_protocol (TpAccountManager *account_manager,
776 TpProtocol *protocol,
777 const gchar *display_name)
778 {
779 g_return_val_if_fail (TP_IS_ACCOUNT_MANAGER (account_manager), NULL);
780 g_return_val_if_fail (TP_IS_PROTOCOL (protocol), NULL);
781
782 return g_object_new (TP_TYPE_ACCOUNT_REQUEST,
783 "account-manager", account_manager,
784 "connection-manager", tp_protocol_get_cm_name (protocol),
785 "protocol", tp_protocol_get_name (protocol),
786 "display-name", display_name,
787 NULL);
788 }
789
790 /**
791 * tp_account_request_set_display_name:
792 * @self: a #TpAccountRequest
793 * @name: a display name for the account
794 *
795 * Set the display name for the new account, @self, to @name. Use the
796 * #TpAccountRequest:display-name property to read the current display
797 * name.
798 *
799 * Since: 0.19.1
800 */
801 void
tp_account_request_set_display_name(TpAccountRequest * self,const gchar * name)802 tp_account_request_set_display_name (TpAccountRequest *self,
803 const gchar *name)
804 {
805 TpAccountRequestPrivate *priv;
806
807 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
808 g_return_if_fail (name != NULL);
809
810 priv = self->priv;
811
812 g_return_if_fail (priv->result == NULL && !priv->created);
813
814 g_free (priv->display_name);
815 priv->display_name = g_strdup (name);
816 }
817
818 /**
819 * tp_account_request_set_icon_name:
820 * @self: a #TpAccountRequest
821 * @icon: an icon name for the account
822 *
823 * Set the icon name for the new account, @self, to @icon. Use the
824 * #TpAccountRequest:icon-name property to read the current icon name.
825 *
826 * Since: 0.19.1
827 */
828 void
tp_account_request_set_icon_name(TpAccountRequest * self,const gchar * icon)829 tp_account_request_set_icon_name (TpAccountRequest *self,
830 const gchar *icon)
831 {
832 TpAccountRequestPrivate *priv;
833
834 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
835 g_return_if_fail (icon != NULL);
836
837 priv = self->priv;
838
839 g_return_if_fail (priv->result == NULL && !priv->created);
840
841 tp_asv_set_string (priv->properties, TP_PROP_ACCOUNT_ICON, icon);
842 }
843
844 /**
845 * tp_account_request_set_nickname:
846 * @self: a #TpAccountRequest
847 * @nickname: a nickname for the account
848 *
849 * Set the nickname for the new account, @self, to @nickname. Use the
850 * #TpAccountRequest:nickname property to read the current nickname.
851 *
852 * Since: 0.19.1
853 */
854 void
tp_account_request_set_nickname(TpAccountRequest * self,const gchar * nickname)855 tp_account_request_set_nickname (TpAccountRequest *self,
856 const gchar *nickname)
857 {
858 TpAccountRequestPrivate *priv;
859
860 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
861 g_return_if_fail (nickname != NULL);
862
863 priv = self->priv;
864
865 g_return_if_fail (priv->result == NULL && !priv->created);
866
867 tp_asv_set_string (priv->properties, TP_PROP_ACCOUNT_NICKNAME, nickname);
868 }
869
870 /**
871 * tp_account_request_set_requested_presence:
872 * @self: a #TpAccountRequest
873 * @presence: the requested presence type
874 * @status: the requested presence status
875 * @message: the requested presence message
876 *
877 * Set the requested presence for the new account, @self, to the type
878 * (@presence, @status), with message @message. Use the
879 * #TpAccountRequest:requested-presence-type,
880 * #TpAccountRequest:requested-status, and
881 * #TpAccountRequest:requested-status-message properties to read the
882 * current requested presence.
883 *
884 * Since: 0.19.1
885 */
886 void
tp_account_request_set_requested_presence(TpAccountRequest * self,TpConnectionPresenceType presence,const gchar * status,const gchar * message)887 tp_account_request_set_requested_presence (TpAccountRequest *self,
888 TpConnectionPresenceType presence,
889 const gchar *status,
890 const gchar *message)
891 {
892 TpAccountRequestPrivate *priv;
893 GValue *value;
894 GValueArray *arr;
895
896 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
897
898 priv = self->priv;
899
900 g_return_if_fail (priv->result == NULL && !priv->created);
901
902 value = tp_g_value_slice_new_take_boxed (TP_STRUCT_TYPE_SIMPLE_PRESENCE,
903 dbus_g_type_specialized_construct (TP_STRUCT_TYPE_SIMPLE_PRESENCE));
904 arr = (GValueArray *) g_value_get_boxed (value);
905
906 g_value_set_uint (arr->values, presence);
907 g_value_set_string (arr->values + 1, status);
908 g_value_set_string (arr->values + 2, message);
909
910 g_hash_table_insert (priv->properties,
911 TP_PROP_ACCOUNT_REQUESTED_PRESENCE, value);
912 }
913
914 /**
915 * tp_account_request_set_automatic_presence:
916 * @self: a #TpAccountRequest
917 * @presence: the automatic presence type
918 * @status: the automatic presence status
919 * @message: the automatic presence message
920 *
921 * Set the automatic presence for the new account, @self, to the type
922 * (@presence, @status), with message @message. Use the
923 * #TpAccountRequest:automatic-presence-type,
924 * #TpAccountRequest:automatic-status, and
925 * #TpAccountRequest:automatic-status-message properties to read the
926 * current automatic presence.
927 *
928 * Since: 0.19.1
929 */
930 void
tp_account_request_set_automatic_presence(TpAccountRequest * self,TpConnectionPresenceType presence,const gchar * status,const gchar * message)931 tp_account_request_set_automatic_presence (TpAccountRequest *self,
932 TpConnectionPresenceType presence,
933 const gchar *status,
934 const gchar *message)
935 {
936 TpAccountRequestPrivate *priv;
937 GValue *value;
938 GValueArray *arr;
939
940 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
941
942 priv = self->priv;
943
944 g_return_if_fail (priv->result == NULL && !priv->created);
945
946 value = tp_g_value_slice_new_take_boxed (TP_STRUCT_TYPE_SIMPLE_PRESENCE,
947 dbus_g_type_specialized_construct (TP_STRUCT_TYPE_SIMPLE_PRESENCE));
948 arr = (GValueArray *) g_value_get_boxed (value);
949
950 g_value_set_uint (arr->values, presence);
951 g_value_set_string (arr->values + 1, status);
952 g_value_set_string (arr->values + 2, message);
953
954 g_hash_table_insert (priv->properties,
955 TP_PROP_ACCOUNT_AUTOMATIC_PRESENCE, value);
956 }
957
958 /**
959 * tp_account_request_set_enabled:
960 * @self: a #TpAccountRequest
961 * @enabled: %TRUE if the account is to be enabled
962 *
963 * Set the enabled property of the account on creation to
964 * @enabled. Use the #TpAccountRequest:enabled property to read the
965 * current enabled value.
966 *
967 * Since: 0.19.1
968 */
969 void
tp_account_request_set_enabled(TpAccountRequest * self,gboolean enabled)970 tp_account_request_set_enabled (TpAccountRequest *self,
971 gboolean enabled)
972 {
973 TpAccountRequestPrivate *priv;
974
975 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
976
977 priv = self->priv;
978
979 g_return_if_fail (priv->result == NULL && !priv->created);
980
981 tp_asv_set_boolean (priv->properties, TP_PROP_ACCOUNT_ENABLED, enabled);
982 }
983
984 /**
985 * tp_account_request_set_connect_automatically:
986 * @self: a #TpAccountRequest
987 * @connect_automatically: %TRUE if the account is to connect automatically
988 *
989 * Set the connect automatically property of the account on creation
990 * to @connect_automatically so that the account is brought online to
991 * the automatic presence. Use the
992 * #TpAccountRequest:connect-automatically property to read the current
993 * connect automatically value.
994 *
995 * Since: 0.19.1
996 */
997 void
tp_account_request_set_connect_automatically(TpAccountRequest * self,gboolean connect_automatically)998 tp_account_request_set_connect_automatically (TpAccountRequest *self,
999 gboolean connect_automatically)
1000 {
1001 TpAccountRequestPrivate *priv;
1002
1003 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
1004
1005 priv = self->priv;
1006
1007 g_return_if_fail (priv->result == NULL && !priv->created);
1008
1009 tp_asv_set_boolean (priv->properties,
1010 TP_PROP_ACCOUNT_CONNECT_AUTOMATICALLY,
1011 connect_automatically);
1012 }
1013
1014 /**
1015 * tp_account_request_add_supersedes:
1016 * @self: a #TpAccountRequest
1017 * @superseded_path: an account object path to add to the supersedes
1018 * list
1019 *
1020 * Add an account object path to the list of superseded accounts which
1021 * this new account will supersede. Use the
1022 * #TpAccountRequest:supersedes property to read the current list of
1023 * superseded accounts.
1024 *
1025 * Since: 0.19.1
1026 */
1027 void
tp_account_request_add_supersedes(TpAccountRequest * self,const gchar * superseded_path)1028 tp_account_request_add_supersedes (TpAccountRequest *self,
1029 const gchar *superseded_path)
1030 {
1031 TpAccountRequestPrivate *priv;
1032 GPtrArray *array;
1033
1034 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
1035 g_return_if_fail (g_variant_is_object_path (superseded_path));
1036
1037 priv = self->priv;
1038
1039 g_return_if_fail (priv->result == NULL && !priv->created);
1040
1041 array = tp_asv_get_boxed (priv->properties,
1042 TP_PROP_ACCOUNT_SUPERSEDES,
1043 TP_ARRAY_TYPE_OBJECT_PATH_LIST);
1044
1045 if (array == NULL)
1046 {
1047 array = g_ptr_array_new ();
1048
1049 tp_asv_take_boxed (priv->properties,
1050 TP_PROP_ACCOUNT_SUPERSEDES,
1051 TP_ARRAY_TYPE_OBJECT_PATH_LIST, array);
1052 }
1053
1054 g_ptr_array_add (array, g_strdup (superseded_path));
1055 }
1056
1057 /**
1058 * tp_account_request_set_avatar:
1059 * @self: a #TpAccountRequest
1060 * @avatar: (allow-none) (array length=len): a new avatar to set; can
1061 * be %NULL only if %len equals 0
1062 * @len: the length of the new avatar
1063 * @mime_type: (allow-none): the MIME type of the new avatar; can be %NULL
1064 * only if @len equals 0
1065 *
1066 * Set the avatar of the account @self to @avatar. Use the
1067 * #TpAccountRequest:avatar and #TpAccountRequest:avatar-mime-type
1068 * properties to read the current avatar.
1069 *
1070 * Since: 0.19.1
1071 */
1072 void
tp_account_request_set_avatar(TpAccountRequest * self,const guchar * avatar,gsize len,const gchar * mime_type)1073 tp_account_request_set_avatar (TpAccountRequest *self,
1074 const guchar *avatar,
1075 gsize len,
1076 const gchar *mime_type)
1077 {
1078 TpAccountRequestPrivate *priv;
1079 GArray *tmp;
1080 GValueArray *arr;
1081
1082 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
1083 g_return_if_fail (avatar != NULL || len == 0);
1084 g_return_if_fail (mime_type != NULL || len == 0);
1085
1086 priv = self->priv;
1087
1088 g_return_if_fail (priv->result == NULL && !priv->created);
1089
1090 tmp = g_array_new (FALSE, FALSE, sizeof (guchar));
1091
1092 if (len > 0)
1093 g_array_append_vals (tmp, avatar, len);
1094
1095 arr = tp_value_array_build (2,
1096 TP_TYPE_UCHAR_ARRAY, tmp,
1097 G_TYPE_STRING, mime_type,
1098 G_TYPE_INVALID);
1099
1100 g_array_unref (tmp);
1101
1102 tp_asv_take_boxed (priv->properties,
1103 TP_PROP_ACCOUNT_INTERFACE_AVATAR_AVATAR,
1104 TP_STRUCT_TYPE_AVATAR, arr);
1105 }
1106
1107 /**
1108 * tp_account_request_set_service:
1109 * @self: a #TpAccountRequest
1110 * @service: the service name for
1111 *
1112 * Set the service property of the account to @service. Use the
1113 * #TpAccountRequest:service property to read the current value.
1114 *
1115 * Since: 0.19.1
1116 */
1117 void
tp_account_request_set_service(TpAccountRequest * self,const gchar * service)1118 tp_account_request_set_service (TpAccountRequest *self,
1119 const gchar *service)
1120 {
1121 TpAccountRequestPrivate *priv;
1122
1123 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
1124 g_return_if_fail (service != NULL);
1125
1126 priv = self->priv;
1127
1128 g_return_if_fail (priv->result == NULL && !priv->created);
1129
1130 tp_asv_set_string (priv->properties,
1131 TP_PROP_ACCOUNT_SERVICE, service);
1132 }
1133
1134 /**
1135 * tp_account_request_set_storage_provider:
1136 * @self: a #TpAccountRequest
1137 * @provider: the name of an account storage implementation
1138 *
1139 * Set the account storage to use when creating the account. Use the
1140 * #TpAccountRequest:storage-provider property to read the current value.
1141 *
1142 * Since: 0.19.4
1143 */
1144 void
tp_account_request_set_storage_provider(TpAccountRequest * self,const gchar * provider)1145 tp_account_request_set_storage_provider (TpAccountRequest *self,
1146 const gchar *provider)
1147 {
1148 TpAccountRequestPrivate *priv;
1149
1150 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
1151
1152 priv = self->priv;
1153
1154 g_return_if_fail (priv->result == NULL && !priv->created);
1155
1156 tp_asv_set_string (priv->properties,
1157 TP_PROP_ACCOUNT_INTERFACE_STORAGE_STORAGE_PROVIDER, provider);
1158 }
1159
1160 /**
1161 * tp_account_request_set_parameter:
1162 * @self: a #TpAccountRequest
1163 * @key: the parameter key
1164 * @value: (transfer none): a variant containing the parameter value
1165 *
1166 * Set an account parameter, @key, to @value. Use the
1167 * #TpAccountRequest:parameters property to read the current list of
1168 * set parameters.
1169 *
1170 * Parameters can be unset using tp_account_request_unset_parameter().
1171 *
1172 * Since: 0.19.1
1173 */
1174 void
tp_account_request_set_parameter(TpAccountRequest * self,const gchar * key,GVariant * value)1175 tp_account_request_set_parameter (TpAccountRequest *self,
1176 const gchar *key,
1177 GVariant *value)
1178 {
1179 TpAccountRequestPrivate *priv;
1180 GValue one = G_VALUE_INIT, *two;
1181
1182 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
1183 g_return_if_fail (key != NULL);
1184 g_return_if_fail (value != NULL);
1185
1186 priv = self->priv;
1187
1188 g_return_if_fail (priv->result == NULL && !priv->created);
1189
1190 dbus_g_value_parse_g_variant (value, &one);
1191 two = tp_g_value_slice_dup (&one);
1192
1193 g_hash_table_insert (priv->parameters, g_strdup (key), two);
1194
1195 g_value_unset (&one);
1196 }
1197
1198 /**
1199 * tp_account_request_unset_parameter:
1200 * @self: a #TpAccountRequest
1201 * @key: the parameter key
1202 *
1203 * Unset the account parameter @key which has previously been set
1204 * using tp_account_request_set_parameter() or another convenience
1205 * function.
1206 *
1207 * Since: 0.19.1
1208 */
1209 void
tp_account_request_unset_parameter(TpAccountRequest * self,const gchar * key)1210 tp_account_request_unset_parameter (TpAccountRequest *self,
1211 const gchar *key)
1212 {
1213 TpAccountRequestPrivate *priv;
1214
1215 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
1216 g_return_if_fail (key != NULL);
1217
1218 priv = self->priv;
1219
1220 g_return_if_fail (priv->result == NULL && !priv->created);
1221
1222 g_hash_table_remove (priv->parameters, key);
1223 }
1224
1225 /**
1226 * tp_account_request_set_parameter_string: (skip)
1227 * @self: a #TpAccountRequest
1228 * @key: the parameter key
1229 * @value: the parameter value
1230 *
1231 * Convenience function to set an account parameter string value. See
1232 * tp_account_request_set_parameter() for more details.
1233 *
1234 * Since: 0.19.1
1235 */
1236 void
tp_account_request_set_parameter_string(TpAccountRequest * self,const gchar * key,const gchar * value)1237 tp_account_request_set_parameter_string (TpAccountRequest *self,
1238 const gchar *key,
1239 const gchar *value)
1240 {
1241 TpAccountRequestPrivate *priv;
1242
1243 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
1244 g_return_if_fail (key != NULL);
1245 g_return_if_fail (value != NULL);
1246
1247 priv = self->priv;
1248
1249 g_return_if_fail (priv->result == NULL && !priv->created);
1250
1251 g_hash_table_insert (priv->parameters, g_strdup (key),
1252 tp_g_value_slice_new_string (value));
1253 }
1254
1255 static void
tp_account_request_account_prepared_cb(GObject * object,GAsyncResult * result,gpointer user_data)1256 tp_account_request_account_prepared_cb (GObject *object,
1257 GAsyncResult *result,
1258 gpointer user_data)
1259 {
1260 TpAccountRequest *self = user_data;
1261 TpAccountRequestPrivate *priv = self->priv;
1262 GError *error = NULL;
1263
1264 if (!tp_proxy_prepare_finish (object, result, &error))
1265 {
1266 DEBUG ("Error preparing account: %s", error->message);
1267 g_simple_async_result_take_error (priv->result, error);
1268 }
1269
1270 g_simple_async_result_complete (priv->result);
1271 g_clear_object (&priv->result);
1272 }
1273
1274 static void
tp_account_request_create_account_cb(TpAccountManager * proxy,const gchar * account_path,const GError * error,gpointer user_data,GObject * weak_object)1275 tp_account_request_create_account_cb (TpAccountManager *proxy,
1276 const gchar *account_path,
1277 const GError *error,
1278 gpointer user_data,
1279 GObject *weak_object)
1280 {
1281 TpAccountRequest *self = TP_ACCOUNT_REQUEST (weak_object);
1282 TpAccountRequestPrivate *priv = self->priv;
1283 GError *e = NULL;
1284 TpAccount *account;
1285 GArray *features;
1286
1287 if (error != NULL)
1288 {
1289 DEBUG ("failed to create account: %s", error->message);
1290 g_simple_async_result_set_from_error (priv->result, error);
1291 g_simple_async_result_complete (priv->result);
1292 g_clear_object (&priv->result);
1293 return;
1294 }
1295
1296 priv->created = TRUE;
1297
1298 account = tp_simple_client_factory_ensure_account (
1299 tp_proxy_get_factory (proxy), account_path, NULL, &e);
1300
1301 if (account == NULL)
1302 {
1303 g_simple_async_result_take_error (priv->result, e);
1304 g_simple_async_result_complete (priv->result);
1305 g_clear_object (&priv->result);
1306 return;
1307 }
1308
1309 /* Give account's ref to the result */
1310 g_simple_async_result_set_op_res_gpointer (priv->result, account,
1311 g_object_unref);
1312
1313 features = tp_simple_client_factory_dup_account_features (
1314 tp_proxy_get_factory (proxy), account);
1315
1316 tp_proxy_prepare_async (account, (GQuark *) features->data,
1317 tp_account_request_account_prepared_cb, self);
1318
1319 g_array_unref (features);
1320 }
1321
1322 /**
1323 * tp_account_request_create_account_async:
1324 * @self: a #TpAccountRequest
1325 * @callback: a function to call when the account has been created
1326 * @user_data: user data to @callback
1327 *
1328 * Start an asynchronous operation to create the account @self on the
1329 * account manager.
1330 *
1331 * @callback will only be called when the newly created #TpAccount has
1332 * the %TP_ACCOUNT_FEATURE_CORE feature ready on it, so when calling
1333 * tp_account_request_create_account_finish(), one can guarantee this
1334 * feature.
1335 *
1336 * Since: 0.19.1
1337 */
1338 void
tp_account_request_create_account_async(TpAccountRequest * self,GAsyncReadyCallback callback,gpointer user_data)1339 tp_account_request_create_account_async (TpAccountRequest *self,
1340 GAsyncReadyCallback callback,
1341 gpointer user_data)
1342 {
1343 TpAccountRequestPrivate *priv = self->priv;
1344
1345 g_return_if_fail (TP_IS_ACCOUNT_REQUEST (self));
1346
1347 priv = self->priv;
1348
1349 if (priv->result != NULL)
1350 {
1351 g_simple_async_report_error_in_idle (G_OBJECT (self),
1352 callback, user_data,
1353 TP_ERROR, TP_ERROR_BUSY,
1354 "An account creation operation has already been started on this "
1355 "account request");
1356 return;
1357 }
1358
1359 if (priv->created)
1360 {
1361 g_simple_async_report_error_in_idle (G_OBJECT (self),
1362 callback, user_data,
1363 TP_ERROR, TP_ERROR_NOT_AVAILABLE,
1364 "This account has already been created");
1365 return;
1366 }
1367
1368 priv->result = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
1369 tp_account_request_create_account_async);
1370
1371 tp_cli_account_manager_call_create_account (priv->account_manager,
1372 -1, priv->cm_name, priv->proto_name, priv->display_name,
1373 priv->parameters, priv->properties,
1374 tp_account_request_create_account_cb, NULL, NULL, G_OBJECT (self));
1375 }
1376
1377 /**
1378 * tp_account_request_create_account_finish:
1379 * @self: a #TpAccountRequest
1380 * @result: a #GAsyncResult
1381 * @error: something
1382 *
1383 * Finishes an asynchronous account creation operation and returns a
1384 * new ref to a #TpAccount object. The returned account will have the
1385 * features listed in tp_simple_client_factory_dup_account_features()
1386 * (with the proxy factory from #TpAccountRequest:account-manager)
1387 * prepared on it.
1388 *
1389 * Returns: (transfer full): a new ref to a #TpAccount, or %NULL
1390 *
1391 * Since: 0.19.1
1392 */
1393 TpAccount *
tp_account_request_create_account_finish(TpAccountRequest * self,GAsyncResult * result,GError ** error)1394 tp_account_request_create_account_finish (TpAccountRequest *self,
1395 GAsyncResult *result,
1396 GError **error)
1397 {
1398 _tp_implement_finish_return_copy_pointer (self,
1399 tp_account_request_create_account_async, g_object_ref);
1400 }
1401