summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2012-04-27 10:44:05 +0200
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2012-04-27 10:44:05 +0200
commit414e19f9d4021cd4b353fff01da1b8ce9ba2df7b (patch)
tree3f3c2b6dc27803bd5f3dd3d7effa88d84864d317
parent2556ea7ff0fceff8dcc893c8b68bbfc596b3f44c (diff)
parent5d2f1f6a6b491a9eb05ff0013a258471d59248de (diff)
Merge branch 'telepathy-glib-0.18'
-rw-r--r--telepathy-glib/proxy.c56
-rw-r--r--tests/dbus/proxy-preparation.c39
-rw-r--r--tests/lib/my-conn-proxy.c30
-rw-r--r--tests/lib/my-conn-proxy.h9
4 files changed, 123 insertions, 11 deletions
diff --git a/telepathy-glib/proxy.c b/telepathy-glib/proxy.c
index 61538189a..9f8ac0734 100644
--- a/telepathy-glib/proxy.c
+++ b/telepathy-glib/proxy.c
@@ -332,6 +332,11 @@ typedef enum {
FEATURE_STATE_WANTED,
/* Want to prepare, have called prepare_async */
FEATURE_STATE_TRYING,
+ /* Couldn't prepare because a required interface on the connection
+ * was missing and the connection wasn't connected yet. We'll retry to
+ * prepare once the connection is connected.
+ * This state is only used when preparing Connection features */
+ FEATURE_STATE_MISSING_IFACE,
/* Couldn't prepare, gave up */
FEATURE_STATE_FAILED,
/* Prepared */
@@ -1798,6 +1803,7 @@ check_depends_ready (TpProxy *self,
return FALSE;
case FEATURE_STATE_FAILED:
+ case FEATURE_STATE_MISSING_IFACE:
if (!can_retry || !dep_feature->can_retry)
{
DEBUG ("Can't prepare %s, because %s (a dependency) is "
@@ -2098,8 +2104,21 @@ request_is_complete (TpProxy *self,
* in tp_proxy_prepare_async() as CORE have to be prepared */
if (!check_feature_interfaces (self, feature))
{
- tp_proxy_set_feature_state (self, feature,
- FEATURE_STATE_FAILED);
+ if (TP_IS_CONNECTION (self) &&
+ tp_connection_get_status ((TpConnection *) self, NULL)
+ != TP_CONNECTION_STATUS_CONNECTED)
+ {
+ /* Give a chance to retry preparing the feature once
+ * the Connection is connected as it may still gain
+ * the interface. */
+ tp_proxy_set_feature_state (self, feature,
+ FEATURE_STATE_MISSING_IFACE);
+ }
+ else
+ {
+ tp_proxy_set_feature_state (self, feature,
+ FEATURE_STATE_FAILED);
+ }
continue;
}
@@ -2135,6 +2154,7 @@ request_is_complete (TpProxy *self,
case FEATURE_STATE_INVALID:
case FEATURE_STATE_FAILED:
+ case FEATURE_STATE_MISSING_IFACE:
case FEATURE_STATE_READY:
/* nothing more to do */
break;
@@ -2327,20 +2347,34 @@ static void foreach_feature (GQuark name,
{
FeatureState state = GPOINTER_TO_INT (data);
TpProxy *self = user_data;
- const TpProxyFeature *feature;
- if (state != FEATURE_STATE_READY)
- return;
+ if (state == FEATURE_STATE_MISSING_IFACE)
+ {
+ GQuark features[] = { 0, 0};
- feature = tp_proxy_subclass_get_feature (G_OBJECT_TYPE (self), name);
+ tp_proxy_set_feature_state (self, name, FEATURE_STATE_UNWANTED);
- if (feature->prepare_before_signalling_connected_async == NULL)
- return;
+ self->priv->pending_will_announce_calls++;
- self->priv->pending_will_announce_calls++;
+ features[0] = name;
- feature->prepare_before_signalling_connected_async (self, feature,
- prepare_before_signalling_connected_cb, self);
+ tp_proxy_prepare_async (self, features,
+ prepare_before_signalling_connected_cb, self);
+ }
+ else if (state == FEATURE_STATE_READY)
+ {
+ const TpProxyFeature *feature;
+
+ feature = tp_proxy_subclass_get_feature (G_OBJECT_TYPE (self), name);
+
+ if (feature->prepare_before_signalling_connected_async == NULL)
+ return;
+
+ self->priv->pending_will_announce_calls++;
+
+ feature->prepare_before_signalling_connected_async (self, feature,
+ prepare_before_signalling_connected_cb, self);
+ }
}
/*
diff --git a/tests/dbus/proxy-preparation.c b/tests/dbus/proxy-preparation.c
index df4b1b7e5..7d7638fd5 100644
--- a/tests/dbus/proxy-preparation.c
+++ b/tests/dbus/proxy-preparation.c
@@ -368,6 +368,43 @@ test_before_connected (Test *test,
BEFORE_CONNECTED_STATE_CONNECTED);
}
+static void
+test_interface_later (Test *test,
+ gconstpointer data G_GNUC_UNUSED)
+{
+ GQuark features[] = { TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER, 0 };
+ GQuark connected[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 };
+ const gchar *interfaces[] = { TP_TESTS_MY_CONN_PROXY_IFACE_LATER, NULL };
+
+ /* We need a not yet connected connection */
+ recreate_connection (test);
+
+ /* Try preparing before the connection is connected */
+ tp_proxy_prepare_async (test->my_conn, features, prepare_cb, test);
+
+ g_main_loop_run (test->mainloop);
+ g_assert_no_error (test->error);
+
+ /* Feature isn't prepared */
+ g_assert (!tp_proxy_is_prepared (test->my_conn,
+ TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER));
+
+ tp_cli_connection_call_connect (test->connection, -1, NULL, NULL, NULL, NULL);
+
+ /* While connecting the interface is added */
+ tp_base_connection_add_interfaces (test->base_connection, interfaces);
+
+ /* Wait that CONNECTED is announced */
+ tp_proxy_prepare_async (test->my_conn, connected, prepare_cb, test);
+
+ g_main_loop_run (test->mainloop);
+ g_assert_no_error (test->error);
+
+ /* The feature has been prepared now */
+ g_assert (tp_proxy_is_prepared (test->my_conn,
+ TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER));
+}
+
int
main (int argc,
char **argv)
@@ -395,6 +432,8 @@ main (int argc,
test_retry_dep, teardown);
g_test_add ("/proxy-preparation/before-connected", Test, NULL, setup,
test_before_connected, teardown);
+ g_test_add ("/proxy-preparation/interface-later", Test, NULL, setup,
+ test_interface_later, teardown);
return g_test_run ();
}
diff --git a/tests/lib/my-conn-proxy.c b/tests/lib/my-conn-proxy.c
index 208f00449..d7748f355 100644
--- a/tests/lib/my-conn-proxy.c
+++ b/tests/lib/my-conn-proxy.c
@@ -33,6 +33,7 @@ enum {
FEAT_RETRY,
FEAT_RETRY_DEP,
FEAT_BEFORE_CONNECTED,
+ FEAT_INTERFACE_LATER,
N_FEAT
};
@@ -203,6 +204,21 @@ prepare_before_connected_before_async (TpProxy *proxy,
g_object_unref (result);
}
+static void
+prepare_interface_later_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+
+ result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
+ prepare_interface_later_async);
+
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+}
+
static const TpProxyFeature *
list_features (TpProxyClass *cls G_GNUC_UNUSED)
{
@@ -212,6 +228,7 @@ list_features (TpProxyClass *cls G_GNUC_UNUSED)
static GQuark need_wrong_iface[2] = {0, 0};
static GQuark need_fail[2] = {0, 0};
static GQuark need_retry[2] = {0, 0};
+ static GQuark need_iface_later[2] = {0, 0};
if (G_LIKELY (features[0].name != 0))
return features;
@@ -262,6 +279,13 @@ list_features (TpProxyClass *cls G_GNUC_UNUSED)
features[FEAT_BEFORE_CONNECTED].prepare_before_signalling_connected_async =
prepare_before_connected_before_async;
+ features[FEAT_INTERFACE_LATER].name =
+ TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER;
+ features[FEAT_INTERFACE_LATER].prepare_async = prepare_interface_later_async;
+ need_iface_later[0] = g_quark_from_static_string (
+ TP_TESTS_MY_CONN_PROXY_IFACE_LATER);
+ features[FEAT_INTERFACE_LATER].interfaces_needed = need_iface_later;
+
return features;
}
@@ -332,3 +356,9 @@ tp_tests_my_conn_proxy_get_feature_quark_before_connected (void)
{
return g_quark_from_static_string ("tp-my-conn-proxy-feature-before-connected");
}
+
+GQuark
+tp_tests_my_conn_proxy_get_feature_quark_interface_later (void)
+{
+ return g_quark_from_static_string ("tp-my-conn-proxy-feature-interface-later");
+}
diff --git a/tests/lib/my-conn-proxy.h b/tests/lib/my-conn-proxy.h
index cfc821604..08be18b93 100644
--- a/tests/lib/my-conn-proxy.h
+++ b/tests/lib/my-conn-proxy.h
@@ -110,6 +110,15 @@ GQuark tp_tests_my_conn_proxy_get_feature_quark_retry_dep (void) G_GNUC_CONST;
(tp_tests_my_conn_proxy_get_feature_quark_before_connected ())
GQuark tp_tests_my_conn_proxy_get_feature_quark_before_connected (void) G_GNUC_CONST;
+#define TP_TESTS_MY_CONN_PROXY_IFACE_LATER "org.freedesktop.Telepathy.Conncetion.Interface.Test.Later"
+
+/* Need the interface TP_TESTS_MY_CONN_PROXY_IFACE_LATER to be prepared but
+ * this interface is not in the initial set of interfaces of the connection.
+ * It is added when the connection is connected. */
+#define TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER \
+ (tp_tests_my_conn_proxy_get_feature_quark_interface_later ())
+GQuark tp_tests_my_conn_proxy_get_feature_quark_interface_later (void) G_GNUC_CONST;
+
G_END_DECLS
#endif /* #ifndef __TP_TESTS_MY_CONN_PROXY_H__ */