~tiagosh/telepathy-qt/group-chat2

« back to all changes in this revision

Viewing changes to tests/lib/glib/bug16307-conn.c

  • Committer: Package Import Robot
  • Author(s): Ricardo Salveti de Araujo
  • Date: 2013-06-06 04:56:14 UTC
  • Revision ID: package-import@ubuntu.com-20130606045614-inpxexo6765rnmp1
Tags: upstream-0.9.3
ImportĀ upstreamĀ versionĀ 0.9.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * bug16307-conn.c - connection that reproduces the #15307 bug
 
3
 *
 
4
 * Copyright (C) 2007-2008 Collabora Ltd. <http://www.collabora.co.uk/>
 
5
 * Copyright (C) 2007-2008 Nokia Corporation
 
6
 *
 
7
 * Copying and distribution of this file, with or without modification,
 
8
 * are permitted in any medium without royalty provided the copyright
 
9
 * notice and this notice are preserved.
 
10
 */
 
11
#include "bug16307-conn.h"
 
12
 
 
13
#include <dbus/dbus-glib.h>
 
14
 
 
15
#include <telepathy-glib/interfaces.h>
 
16
#include <telepathy-glib/dbus.h>
 
17
#include <telepathy-glib/errors.h>
 
18
#include <telepathy-glib/gtypes.h>
 
19
#include <telepathy-glib/handle-repo-dynamic.h>
 
20
#include <telepathy-glib/util.h>
 
21
 
 
22
static void service_iface_init (gpointer, gpointer);
 
23
 
 
24
G_DEFINE_TYPE_WITH_CODE (TpTestsBug16307Connection,
 
25
    tp_tests_bug16307_connection,
 
26
    TP_TESTS_TYPE_SIMPLE_CONNECTION,
 
27
    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION,
 
28
      service_iface_init);
 
29
    G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_ALIASING,
 
30
      NULL);
 
31
    );
 
32
 
 
33
/* type definition stuff */
 
34
 
 
35
enum
 
36
{
 
37
  SIGNAL_GET_STATUS_RECEIVED,
 
38
  N_SIGNALS
 
39
};
 
40
 
 
41
static guint signals[N_SIGNALS] = {0};
 
42
 
 
43
struct _TpTestsBug16307ConnectionPrivate
 
44
{
 
45
  /* In a real connection manager, the underlying implementation start
 
46
   * connecting, then go to state CONNECTED when finished. Here there isn't
 
47
   * actually a connection, so the connection process is fake and the time
 
48
   * when it connects is, for this test purpose, when the D-Bus method GetStatus
 
49
   * is called.
 
50
   *
 
51
   * Also, the GetStatus D-Bus reply is delayed until
 
52
   * tp_tests_bug16307_connection_inject_get_status_return() is called
 
53
   */
 
54
  DBusGMethodInvocation *get_status_invocation;
 
55
};
 
56
 
 
57
static void
 
58
tp_tests_bug16307_connection_init (TpTestsBug16307Connection *self)
 
59
{
 
60
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
 
61
      TP_TESTS_TYPE_BUG16307_CONNECTION, TpTestsBug16307ConnectionPrivate);
 
62
}
 
63
 
 
64
static void
 
65
finalize (GObject *object)
 
66
{
 
67
  G_OBJECT_CLASS (tp_tests_bug16307_connection_parent_class)->finalize (object);
 
68
}
 
69
 
 
70
static gboolean
 
71
pretend_connected (gpointer data)
 
72
{
 
73
  TpTestsBug16307Connection *self = TP_TESTS_BUG16307_CONNECTION (data);
 
74
  TpBaseConnection *conn = (TpBaseConnection *) self;
 
75
  TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn,
 
76
      TP_HANDLE_TYPE_CONTACT);
 
77
  gchar *account;
 
78
 
 
79
  g_object_get (self, "account", &account, NULL);
 
80
 
 
81
  conn->self_handle = tp_handle_ensure (contact_repo, account,
 
82
      NULL, NULL);
 
83
 
 
84
  g_free (account);
 
85
 
 
86
  tp_base_connection_change_status (conn, TP_CONNECTION_STATUS_CONNECTED,
 
87
      TP_CONNECTION_STATUS_REASON_REQUESTED);
 
88
 
 
89
  return FALSE;
 
90
}
 
91
 
 
92
void
 
93
tp_tests_bug16307_connection_inject_get_status_return (TpTestsBug16307Connection *self)
 
94
{
 
95
  TpBaseConnection *self_base = TP_BASE_CONNECTION (self);
 
96
  DBusGMethodInvocation *context;
 
97
  gulong get_signal_id;
 
98
 
 
99
  /* if we don't have a pending get_status yet, wait for it */
 
100
  if (self->priv->get_status_invocation == NULL)
 
101
    {
 
102
      GMainLoop *loop = g_main_loop_new (NULL, FALSE);
 
103
 
 
104
      get_signal_id = g_signal_connect_swapped (self, "get-status-received",
 
105
          G_CALLBACK (g_main_loop_quit), loop);
 
106
 
 
107
      g_main_loop_run (loop);
 
108
 
 
109
      g_signal_handler_disconnect (self, get_signal_id);
 
110
 
 
111
      g_main_loop_unref (loop);
 
112
    }
 
113
 
 
114
  context = self->priv->get_status_invocation;
 
115
  g_assert (context != NULL);
 
116
 
 
117
  if (self_base->status == TP_INTERNAL_CONNECTION_STATUS_NEW)
 
118
    {
 
119
      tp_svc_connection_return_from_get_status (
 
120
          context, TP_CONNECTION_STATUS_DISCONNECTED);
 
121
    }
 
122
  else
 
123
    {
 
124
      tp_svc_connection_return_from_get_status (
 
125
          context, self_base->status);
 
126
    }
 
127
 
 
128
  self->priv->get_status_invocation = NULL;
 
129
}
 
130
 
 
131
static gboolean
 
132
start_connecting (TpBaseConnection *conn,
 
133
                  GError **error)
 
134
{
 
135
  tp_base_connection_change_status (conn, TP_CONNECTION_STATUS_CONNECTING,
 
136
      TP_CONNECTION_STATUS_REASON_REQUESTED);
 
137
 
 
138
  return TRUE;
 
139
}
 
140
 
 
141
static void
 
142
tp_tests_bug16307_connection_class_init (TpTestsBug16307ConnectionClass *klass)
 
143
{
 
144
  TpBaseConnectionClass *base_class =
 
145
      (TpBaseConnectionClass *) klass;
 
146
  GObjectClass *object_class = (GObjectClass *) klass;
 
147
  static const gchar *interfaces_always_present[] = {
 
148
      TP_IFACE_CONNECTION_INTERFACE_ALIASING,
 
149
      TP_IFACE_CONNECTION_INTERFACE_CAPABILITIES,
 
150
      TP_IFACE_CONNECTION_INTERFACE_PRESENCE,
 
151
      TP_IFACE_CONNECTION_INTERFACE_AVATARS,
 
152
      NULL };
 
153
  static TpDBusPropertiesMixinPropImpl connection_properties[] = {
 
154
      { "Status", "dbus-status-except-i-broke-it", NULL },
 
155
      { NULL }
 
156
  };
 
157
 
 
158
  object_class->finalize = finalize;
 
159
  g_type_class_add_private (klass, sizeof (TpTestsBug16307ConnectionPrivate));
 
160
 
 
161
  base_class->start_connecting = start_connecting;
 
162
 
 
163
  base_class->interfaces_always_present = interfaces_always_present;
 
164
 
 
165
  signals[SIGNAL_GET_STATUS_RECEIVED] = g_signal_new ("get-status-received",
 
166
      G_OBJECT_CLASS_TYPE (klass),
 
167
      G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
 
168
      0,
 
169
      NULL, NULL,
 
170
      g_cclosure_marshal_VOID__VOID,
 
171
      G_TYPE_NONE, 0);
 
172
 
 
173
  /* break the Connection D-Bus properties implementation, so that we always
 
174
   * cause the slower introspection codepath (the one that actually calls
 
175
   * GetStatus) in TpConnection to be invoked */
 
176
  tp_dbus_properties_mixin_implement_interface (object_class,
 
177
      TP_IFACE_QUARK_CONNECTION,
 
178
      NULL, NULL, connection_properties);
 
179
}
 
180
 
 
181
/**
 
182
 * tp_tests_bug16307_connection_get_status
 
183
 *
 
184
 * Implements D-Bus method GetStatus
 
185
 * on interface org.freedesktop.Telepathy.Connection
 
186
 */
 
187
static void
 
188
tp_tests_bug16307_connection_get_status (TpSvcConnection *iface,
 
189
                              DBusGMethodInvocation *context)
 
190
{
 
191
  TpBaseConnection *self_base = TP_BASE_CONNECTION (iface);
 
192
  TpTestsBug16307Connection *self = TP_TESTS_BUG16307_CONNECTION (iface);
 
193
 
 
194
  /* auto-connect on get_status */
 
195
  if ((self_base->status == TP_INTERNAL_CONNECTION_STATUS_NEW ||
 
196
       self_base->status == TP_CONNECTION_STATUS_DISCONNECTED))
 
197
    {
 
198
      pretend_connected (self);
 
199
    }
 
200
 
 
201
  /* D-Bus return call later */
 
202
  g_assert (self->priv->get_status_invocation == NULL);
 
203
  g_assert (context != NULL);
 
204
  self->priv->get_status_invocation = context;
 
205
 
 
206
  g_signal_emit (self, signals[SIGNAL_GET_STATUS_RECEIVED], 0);
 
207
}
 
208
 
 
209
 
 
210
static void
 
211
service_iface_init (gpointer g_iface, gpointer iface_data)
 
212
{
 
213
  TpSvcConnectionClass *klass = g_iface;
 
214
 
 
215
#define IMPLEMENT(prefix,x) tp_svc_connection_implement_##x (klass, \
 
216
    tp_tests_bug16307_connection_##prefix##x)
 
217
  IMPLEMENT(,get_status);
 
218
#undef IMPLEMENT
 
219
}
 
220