1 /*
2 * my-conn-proxy.c - a simple subclass of TpConnection
3 *
4 * Copyright (C) 2010-2011 Collabora Ltd. <http://www.collabora.co.uk/>
5 *
6 * Copying and distribution of this file, with or without modification,
7 * are permitted in any medium without royalty provided the copyright
8 * notice and this notice are preserved.
9 */
10
11 #include "config.h"
12
13 #include "my-conn-proxy.h"
14
15 #include <telepathy-glib/telepathy-glib.h>
16
G_DEFINE_TYPE(TpTestsMyConnProxy,tp_tests_my_conn_proxy,TP_TYPE_CONNECTION)17 G_DEFINE_TYPE (TpTestsMyConnProxy, tp_tests_my_conn_proxy,
18 TP_TYPE_CONNECTION)
19
20 static void
21 tp_tests_my_conn_proxy_init (TpTestsMyConnProxy *self)
22 {
23 }
24
25 enum {
26 FEAT_CORE,
27 FEAT_A,
28 FEAT_B,
29 FEAT_WRONG_IFACE,
30 FEAT_BAD_DEP,
31 FEAT_FAIL,
32 FEAT_FAIL_DEP,
33 FEAT_RETRY,
34 FEAT_RETRY_DEP,
35 FEAT_BEFORE_CONNECTED,
36 FEAT_INTERFACE_LATER,
37 N_FEAT
38 };
39
40 static void
prepare_core_async(TpProxy * proxy,const TpProxyFeature * feature,GAsyncReadyCallback callback,gpointer user_data)41 prepare_core_async (TpProxy *proxy,
42 const TpProxyFeature *feature,
43 GAsyncReadyCallback callback,
44 gpointer user_data)
45 {
46 GSimpleAsyncResult *result;
47
48 /* superclass core features are prepared first */
49 g_assert (tp_proxy_is_prepared (proxy, TP_CONNECTION_FEATURE_CORE));
50
51 result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
52 prepare_core_async);
53
54 g_simple_async_result_complete_in_idle (result);
55 g_object_unref (result);
56 }
57
58 static void
prepare_a_async(TpProxy * proxy,const TpProxyFeature * feature,GAsyncReadyCallback callback,gpointer user_data)59 prepare_a_async (TpProxy *proxy,
60 const TpProxyFeature *feature,
61 GAsyncReadyCallback callback,
62 gpointer user_data)
63 {
64 GSimpleAsyncResult *result;
65
66 g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE));
67
68 result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
69 prepare_a_async);
70
71 g_simple_async_result_complete_in_idle (result);
72 g_object_unref (result);
73 }
74
75 static void
prepare_b_async(TpProxy * proxy,const TpProxyFeature * feature,GAsyncReadyCallback callback,gpointer user_data)76 prepare_b_async (TpProxy *proxy,
77 const TpProxyFeature *feature,
78 GAsyncReadyCallback callback,
79 gpointer user_data)
80 {
81 GSimpleAsyncResult *result;
82
83 g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE));
84 g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_A));
85
86 result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
87 prepare_b_async);
88
89 g_simple_async_result_complete_in_idle (result);
90 g_object_unref (result);
91 }
92
93 static void
cannot_be_prepared_async(TpProxy * proxy,const TpProxyFeature * feature,GAsyncReadyCallback callback,gpointer user_data)94 cannot_be_prepared_async (TpProxy *proxy,
95 const TpProxyFeature *feature,
96 GAsyncReadyCallback callback,
97 gpointer user_data)
98 {
99 g_assert_not_reached ();
100 }
101
102 static void
prepare_fail_async(TpProxy * proxy,const TpProxyFeature * feature,GAsyncReadyCallback callback,gpointer user_data)103 prepare_fail_async (TpProxy *proxy,
104 const TpProxyFeature *feature,
105 GAsyncReadyCallback callback,
106 gpointer user_data)
107 {
108 GSimpleAsyncResult *result;
109
110 g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE));
111
112 result = g_simple_async_result_new_error ((GObject *) proxy, callback,
113 user_data, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
114 "No feature for you!");
115
116 g_simple_async_result_complete_in_idle (result);
117 g_object_unref (result);
118 }
119
120 static void
prepare_retry_async(TpProxy * proxy,const TpProxyFeature * feature,GAsyncReadyCallback callback,gpointer user_data)121 prepare_retry_async (TpProxy *proxy,
122 const TpProxyFeature *feature,
123 GAsyncReadyCallback callback,
124 gpointer user_data)
125 {
126 TpTestsMyConnProxy *self = (TpTestsMyConnProxy *) proxy;
127 GSimpleAsyncResult *result;
128
129 result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
130 prepare_retry_async);
131
132 if (!self->retry_feature_success)
133 {
134 /* Fail the first time we try to prepare the feature */
135 g_simple_async_result_set_error (result, TP_ERROR,
136 TP_ERROR_NOT_YET, "Nah");
137 }
138
139 g_simple_async_result_complete_in_idle (result);
140 g_object_unref (result);
141 }
142
143 static void
prepare_retry_dep_async(TpProxy * proxy,const TpProxyFeature * feature,GAsyncReadyCallback callback,gpointer user_data)144 prepare_retry_dep_async (TpProxy *proxy,
145 const TpProxyFeature *feature,
146 GAsyncReadyCallback callback,
147 gpointer user_data)
148 {
149 GSimpleAsyncResult *result;
150
151 g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE));
152
153 result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
154 prepare_retry_dep_async);
155
156 g_simple_async_result_complete_in_idle (result);
157 g_object_unref (result);
158 }
159
160 static void
prepare_before_connected_async(TpProxy * proxy,const TpProxyFeature * feature,GAsyncReadyCallback callback,gpointer user_data)161 prepare_before_connected_async (TpProxy *proxy,
162 const TpProxyFeature *feature,
163 GAsyncReadyCallback callback,
164 gpointer user_data)
165 {
166 TpTestsMyConnProxy *self = (TpTestsMyConnProxy *) proxy;
167 GSimpleAsyncResult *result;
168
169 g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE));
170
171 result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
172 prepare_before_connected_async);
173
174 if (tp_connection_get_status (TP_CONNECTION (self), NULL) ==
175 TP_CONNECTION_STATUS_CONNECTED)
176 self->before_connected_state = BEFORE_CONNECTED_STATE_CONNECTED;
177 else
178 self->before_connected_state = BEFORE_CONNECTED_STATE_NOT_CONNECTED;
179
180 g_simple_async_result_complete_in_idle (result);
181 g_object_unref (result);
182 }
183
184 static void
prepare_before_connected_before_async(TpProxy * proxy,const TpProxyFeature * feature,GAsyncReadyCallback callback,gpointer user_data)185 prepare_before_connected_before_async (TpProxy *proxy,
186 const TpProxyFeature *feature,
187 GAsyncReadyCallback callback,
188 gpointer user_data)
189 {
190 TpTestsMyConnProxy *self = (TpTestsMyConnProxy *) proxy;
191 GSimpleAsyncResult *result;
192
193 g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE));
194
195 g_assert_cmpuint (tp_connection_get_status (TP_CONNECTION (proxy), NULL), ==,
196 TP_CONNECTION_STATUS_CONNECTING);
197
198 result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
199 prepare_before_connected_before_async);
200
201 self->before_connected_state = BEFORE_CONNECTED_STATE_CONNECTED;
202
203 g_simple_async_result_complete_in_idle (result);
204 g_object_unref (result);
205 }
206
207 static void
prepare_interface_later_async(TpProxy * proxy,const TpProxyFeature * feature,GAsyncReadyCallback callback,gpointer user_data)208 prepare_interface_later_async (TpProxy *proxy,
209 const TpProxyFeature *feature,
210 GAsyncReadyCallback callback,
211 gpointer user_data)
212 {
213 GSimpleAsyncResult *result;
214
215 result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
216 prepare_interface_later_async);
217
218 g_simple_async_result_complete_in_idle (result);
219 g_object_unref (result);
220 }
221
222 static const TpProxyFeature *
list_features(TpProxyClass * cls G_GNUC_UNUSED)223 list_features (TpProxyClass *cls G_GNUC_UNUSED)
224 {
225 static TpProxyFeature features[N_FEAT + 1] = { { 0 } };
226 static GQuark need_a[2] = {0, 0};
227 static GQuark need_channel_core[2] = {0, 0};
228 static GQuark need_wrong_iface[2] = {0, 0};
229 static GQuark need_fail[2] = {0, 0};
230 static GQuark need_retry[2] = {0, 0};
231 static GQuark need_iface_later[2] = {0, 0};
232
233 if (G_LIKELY (features[0].name != 0))
234 return features;
235
236 features[FEAT_CORE].name = TP_TESTS_MY_CONN_PROXY_FEATURE_CORE;
237 features[FEAT_CORE].core = TRUE;
238 features[FEAT_CORE].prepare_async = prepare_core_async;
239
240 features[FEAT_A].name = TP_TESTS_MY_CONN_PROXY_FEATURE_A;
241 features[FEAT_A].prepare_async = prepare_a_async;
242
243 features[FEAT_B].name = TP_TESTS_MY_CONN_PROXY_FEATURE_B;
244 features[FEAT_B].prepare_async = prepare_b_async;
245 need_a[0] = TP_TESTS_MY_CONN_PROXY_FEATURE_A;
246 features[FEAT_B].depends_on = need_a;
247
248 features[FEAT_WRONG_IFACE].name = TP_TESTS_MY_CONN_PROXY_FEATURE_WRONG_IFACE;
249 features[FEAT_WRONG_IFACE].prepare_async = cannot_be_prepared_async;
250 need_channel_core[0] = TP_CHANNEL_FEATURE_CORE;
251 features[FEAT_WRONG_IFACE].interfaces_needed = need_channel_core;
252
253 features[FEAT_BAD_DEP].name = TP_TESTS_MY_CONN_PROXY_FEATURE_BAD_DEP;
254 features[FEAT_BAD_DEP].prepare_async = cannot_be_prepared_async;
255 need_wrong_iface[0] = TP_TESTS_MY_CONN_PROXY_FEATURE_WRONG_IFACE;
256 features[FEAT_BAD_DEP].depends_on = need_wrong_iface;
257
258 features[FEAT_FAIL].name = TP_TESTS_MY_CONN_PROXY_FEATURE_FAIL;
259 features[FEAT_FAIL].prepare_async = prepare_fail_async;
260
261 features[FEAT_FAIL_DEP].name = TP_TESTS_MY_CONN_PROXY_FEATURE_FAIL_DEP;
262 features[FEAT_FAIL_DEP].prepare_async = cannot_be_prepared_async;
263 need_fail[0] = TP_TESTS_MY_CONN_PROXY_FEATURE_FAIL;
264 features[FEAT_FAIL_DEP].depends_on = need_fail;
265
266 features[FEAT_RETRY].name = TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY;
267 features[FEAT_RETRY].prepare_async = prepare_retry_async;
268 features[FEAT_RETRY].can_retry = TRUE;
269
270 features[FEAT_RETRY_DEP].name = TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY_DEP;
271 need_retry[0] = TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY;
272 features[FEAT_RETRY_DEP].prepare_async = prepare_retry_dep_async;
273 features[FEAT_RETRY_DEP].depends_on = need_retry;
274
275 features[FEAT_BEFORE_CONNECTED].name =
276 TP_TESTS_MY_CONN_PROXY_FEATURE_BEFORE_CONNECTED;
277 features[FEAT_BEFORE_CONNECTED].prepare_async =
278 prepare_before_connected_async;
279 features[FEAT_BEFORE_CONNECTED].prepare_before_signalling_connected_async =
280 prepare_before_connected_before_async;
281
282 features[FEAT_INTERFACE_LATER].name =
283 TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER;
284 features[FEAT_INTERFACE_LATER].prepare_async = prepare_interface_later_async;
285 need_iface_later[0] = g_quark_from_static_string (
286 TP_TESTS_MY_CONN_PROXY_IFACE_LATER);
287 features[FEAT_INTERFACE_LATER].interfaces_needed = need_iface_later;
288
289 return features;
290 }
291
292 static void
tp_tests_my_conn_proxy_class_init(TpTestsMyConnProxyClass * klass)293 tp_tests_my_conn_proxy_class_init (TpTestsMyConnProxyClass *klass)
294 {
295 TpProxyClass *proxy_class = (TpProxyClass *) klass;
296
297 proxy_class->list_features = list_features;
298 }
299
300 GQuark
tp_tests_my_conn_proxy_get_feature_quark_core(void)301 tp_tests_my_conn_proxy_get_feature_quark_core (void)
302 {
303 return g_quark_from_static_string ("tp-my-conn-proxy-feature-core");
304 }
305
306 GQuark
tp_tests_my_conn_proxy_get_feature_quark_a(void)307 tp_tests_my_conn_proxy_get_feature_quark_a (void)
308 {
309 return g_quark_from_static_string ("tp-my-conn-proxy-feature-a");
310 }
311
312 GQuark
tp_tests_my_conn_proxy_get_feature_quark_b(void)313 tp_tests_my_conn_proxy_get_feature_quark_b (void)
314 {
315 return g_quark_from_static_string ("tp-my-conn-proxy-feature-b");
316 }
317
318 GQuark
tp_tests_my_conn_proxy_get_feature_quark_wrong_iface(void)319 tp_tests_my_conn_proxy_get_feature_quark_wrong_iface (void)
320 {
321 return g_quark_from_static_string ("tp-my-conn-proxy-feature-wrong_iface");
322 }
323
324 GQuark
tp_tests_my_conn_proxy_get_feature_quark_bad_dep(void)325 tp_tests_my_conn_proxy_get_feature_quark_bad_dep (void)
326 {
327 return g_quark_from_static_string ("tp-my-conn-proxy-feature-bad-dep");
328 }
329
330 GQuark
tp_tests_my_conn_proxy_get_feature_quark_fail(void)331 tp_tests_my_conn_proxy_get_feature_quark_fail (void)
332 {
333 return g_quark_from_static_string ("tp-my-conn-proxy-feature-fail");
334 }
335
336 GQuark
tp_tests_my_conn_proxy_get_feature_quark_fail_dep(void)337 tp_tests_my_conn_proxy_get_feature_quark_fail_dep (void)
338 {
339 return g_quark_from_static_string ("tp-my-conn-proxy-feature-fail-dep");
340 }
341
342 GQuark
tp_tests_my_conn_proxy_get_feature_quark_retry(void)343 tp_tests_my_conn_proxy_get_feature_quark_retry (void)
344 {
345 return g_quark_from_static_string ("tp-my-conn-proxy-feature-retry");
346 }
347
348 GQuark
tp_tests_my_conn_proxy_get_feature_quark_retry_dep(void)349 tp_tests_my_conn_proxy_get_feature_quark_retry_dep (void)
350 {
351 return g_quark_from_static_string ("tp-my-conn-proxy-feature-retry-dep");
352 }
353
354 GQuark
tp_tests_my_conn_proxy_get_feature_quark_before_connected(void)355 tp_tests_my_conn_proxy_get_feature_quark_before_connected (void)
356 {
357 return g_quark_from_static_string ("tp-my-conn-proxy-feature-before-connected");
358 }
359
360 GQuark
tp_tests_my_conn_proxy_get_feature_quark_interface_later(void)361 tp_tests_my_conn_proxy_get_feature_quark_interface_later (void)
362 {
363 return g_quark_from_static_string ("tp-my-conn-proxy-feature-interface-later");
364 }
365