]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-tp-chat.c
TpChat: don't crash with broken TpProperties implementations
[empathy.git] / libempathy / empathy-tp-chat.c
index 02bdc80e396eaf124204ac23f0e023ce11183ced..9eaff95924fa34b6397fde09298119958fe3a805 100644 (file)
@@ -49,13 +49,7 @@ struct _EmpathyTpChatPrivate {
        GQueue                *pending_messages_queue;
        gboolean               had_properties_list;
        GPtrArray             *properties;
-       TpChannelPasswordFlags password_flags;
-       /* TRUE if we fetched the password flag of the channel or if it's not needed
-        * (channel doesn't implement the Password interface) */
-       gboolean               got_password_flags;
        gboolean               can_upgrade_to_muc;
-       gboolean               got_sms_channel;
-       gboolean               sms_channel;
 
        GHashTable            *messages_being_sent;
 
@@ -69,8 +63,6 @@ enum {
        PROP_0,
        PROP_ACCOUNT,
        PROP_REMOTE_CONTACT,
-       PROP_PASSWORD_NEEDED,
-       PROP_SMS_CHANNEL,
        PROP_N_MESSAGES_SENDING,
 };
 
@@ -379,7 +371,7 @@ handle_delivery_report (EmpathyTpChat *self,
         * TpMessage. (fdo #35884) */
        echo = tp_asv_get_boxed (header, "delivery-echo",
                TP_ARRAY_TYPE_MESSAGE_PART_LIST);
-       if (echo != NULL && echo->len >= 1) {
+       if (echo != NULL && echo->len >= 2) {
                const GHashTable *echo_body;
 
                echo_body = g_ptr_array_index (echo, 1);
@@ -694,13 +686,13 @@ tp_chat_list_properties_cb (TpProxy         *proxy,
        GArray            *ids;
        guint              i;
 
-       self->priv->had_properties_list = TRUE;
-
        if (error) {
                DEBUG ("Error listing properties: %s", error->message);
                return;
        }
 
+       self->priv->had_properties_list = TRUE;
+
        ids = g_array_sized_new (FALSE, FALSE, sizeof (guint), properties->len);
        self->priv->properties = g_ptr_array_sized_new (properties->len);
        for (i = 0; i < properties->len; i++) {
@@ -863,22 +855,18 @@ tp_chat_finalize (GObject *object)
 static void
 check_almost_ready (EmpathyTpChat *self)
 {
+       TpChannel *channel = (TpChannel *) self;
+
        if (self->priv->ready_result == NULL)
                return;
 
        if (self->priv->user == NULL)
                return;
 
-       if (!self->priv->got_password_flags)
-               return;
-
-       if (!self->priv->got_sms_channel)
-               return;
-
        /* We need either the members (room) or the remote contact (private chat).
         * If the chat is protected by a password we can't get these information so
         * consider the chat as ready so it can be presented to the user. */
-       if (!empathy_tp_chat_password_needed (self) && self->priv->members == NULL &&
+       if (!tp_channel_password_needed (channel) && self->priv->members == NULL &&
            self->priv->remote_contact == NULL)
                return;
 
@@ -1228,77 +1216,6 @@ tp_chat_got_self_contact_cb (TpConnection            *connection,
        check_almost_ready (self);
 }
 
-static void
-password_flags_changed_cb (TpChannel *channel,
-    guint added,
-    guint removed,
-    gpointer user_data,
-    GObject *weak_object)
-{
-       EmpathyTpChat *self = EMPATHY_TP_CHAT (weak_object);
-       gboolean was_needed, needed;
-
-       was_needed = empathy_tp_chat_password_needed (self);
-
-       self->priv->password_flags |= added;
-       self->priv->password_flags ^= removed;
-
-       needed = empathy_tp_chat_password_needed (self);
-
-       if (was_needed != needed)
-               g_object_notify (G_OBJECT (self), "password-needed");
-}
-
-static void
-got_password_flags_cb (TpChannel *proxy,
-                            guint password_flags,
-                            const GError *error,
-                            gpointer user_data,
-                            GObject *weak_object)
-{
-       EmpathyTpChat *self = EMPATHY_TP_CHAT (weak_object);
-
-       self->priv->got_password_flags = TRUE;
-       self->priv->password_flags = password_flags;
-
-       check_almost_ready (EMPATHY_TP_CHAT (self));
-}
-
-static void
-sms_channel_changed_cb (TpChannel *channel,
-                       gboolean   sms_channel,
-                       gpointer   user_data,
-                       GObject   *chat)
-{
-       EmpathyTpChat *self = (EmpathyTpChat *) chat;
-
-       self->priv->sms_channel = sms_channel;
-
-       g_object_notify (G_OBJECT (chat), "sms-channel");
-}
-
-static void
-get_sms_channel_cb (TpProxy      *channel,
-                   const GValue *value,
-                   const GError *in_error,
-                   gpointer      user_data,
-                   GObject      *chat)
-{
-       EmpathyTpChat *self = (EmpathyTpChat *) chat;
-
-       if (in_error != NULL) {
-               DEBUG ("Failed to get SMSChannel: %s", in_error->message);
-               return;
-       }
-
-       g_return_if_fail (G_VALUE_HOLDS_BOOLEAN (value));
-
-       self->priv->sms_channel = g_value_get_boolean (value);
-       self->priv->got_sms_channel = TRUE;
-
-       check_almost_ready (EMPATHY_TP_CHAT (chat));
-}
-
 static void
 tp_chat_get_property (GObject    *object,
                      guint       param_id,
@@ -1314,12 +1231,6 @@ tp_chat_get_property (GObject    *object,
        case PROP_REMOTE_CONTACT:
                g_value_set_object (value, self->priv->remote_contact);
                break;
-       case PROP_PASSWORD_NEEDED:
-               g_value_set_boolean (value, empathy_tp_chat_password_needed (self));
-               break;
-       case PROP_SMS_CHANNEL:
-               g_value_set_boolean (value, self->priv->sms_channel);
-               break;
        case PROP_N_MESSAGES_SENDING:
                g_value_set_uint (value,
                        g_hash_table_size (self->priv->messages_being_sent));
@@ -1405,22 +1316,6 @@ empathy_tp_chat_class_init (EmpathyTpChatClass *klass)
                                                              EMPATHY_TYPE_CONTACT,
                                                              G_PARAM_READABLE));
 
-       g_object_class_install_property (object_class,
-                                        PROP_PASSWORD_NEEDED,
-                                        g_param_spec_boolean ("password-needed",
-                                                              "password needed",
-                                                              "TRUE if a password is needed to join the channel",
-                                                              FALSE,
-                                                              G_PARAM_READABLE));
-
-       g_object_class_install_property (object_class,
-                                        PROP_SMS_CHANNEL,
-                                        g_param_spec_boolean ("sms-channel",
-                                                              "SMS Channel",
-                                                              "TRUE if channel is for sending SMSes",
-                                                              FALSE,
-                                                              G_PARAM_READABLE));
-
        g_object_class_install_property (object_class,
                                         PROP_N_MESSAGES_SENDING,
                                         g_param_spec_uint ("n-messages-sending",
@@ -1504,7 +1399,9 @@ tp_chat_iface_init (EmpathyContactListIface *iface)
 }
 
 EmpathyTpChat *
-empathy_tp_chat_new (TpAccount *account,
+empathy_tp_chat_new (
+                    TpSimpleClientFactory *factory,
+                    TpAccount *account,
                     TpConnection *conn,
                     const gchar *object_path,
                     const GHashTable *immutable_properties)
@@ -1516,6 +1413,7 @@ empathy_tp_chat_new (TpAccount *account,
        g_return_val_if_fail (immutable_properties != NULL, NULL);
 
        return g_object_new (EMPATHY_TYPE_TP_CHAT,
+                            "factory", factory,
                             "account", account,
                             "connection", conn,
                             "dbus-daemon", conn_proxy->dbus_daemon,
@@ -1601,102 +1499,6 @@ empathy_tp_chat_acknowledge_message (EmpathyTpChat *self,
                                           tp_msg, NULL, NULL);
 }
 
-void
-empathy_tp_chat_acknowledge_messages (EmpathyTpChat *self,
-                                     const GSList *messages) {
-       const GSList *l;
-       GList *messages_to_ack = NULL;
-
-       g_return_if_fail (EMPATHY_IS_TP_CHAT (self));
-
-       if (messages == NULL)
-               return;
-
-       for (l = messages; l != NULL; l = g_slist_next (l)) {
-               EmpathyMessage *message = EMPATHY_MESSAGE (l->data);
-
-               if (empathy_message_is_incoming (message)) {
-                       TpMessage *tp_msg = empathy_message_get_tp_message (message);
-                       messages_to_ack = g_list_append (messages_to_ack, tp_msg);
-               }
-       }
-
-       if (messages_to_ack != NULL) {
-               tp_text_channel_ack_messages_async (TP_TEXT_CHANNEL (self),
-                                                   messages_to_ack, NULL, NULL);
-       }
-
-       g_list_free (messages_to_ack);
-}
-
-void
-empathy_tp_chat_acknowledge_all_messages (EmpathyTpChat *self)
-{
-  empathy_tp_chat_acknowledge_messages (self,
-    (GSList *) empathy_tp_chat_get_pending_messages (self));
-}
-
-gboolean
-empathy_tp_chat_password_needed (EmpathyTpChat *self)
-{
-       return self->priv->password_flags & TP_CHANNEL_PASSWORD_FLAG_PROVIDE;
-}
-
-static void
-provide_password_cb (TpChannel *channel,
-                                     gboolean correct,
-                                     const GError *error,
-                                     gpointer user_data,
-                                     GObject *weak_object)
-{
-       GSimpleAsyncResult *result = user_data;
-
-       if (error != NULL) {
-               g_simple_async_result_set_from_error (result, error);
-       }
-       else if (!correct) {
-               /* The current D-Bus API is a bit weird so re-use the
-                * AuthenticationFailed error */
-               g_simple_async_result_set_error (result, TP_ERRORS,
-                                                TP_ERROR_AUTHENTICATION_FAILED, "Wrong password");
-       }
-
-       g_simple_async_result_complete (result);
-       g_object_unref (result);
-}
-
-void
-empathy_tp_chat_provide_password_async (EmpathyTpChat *self,
-                                                    const gchar *password,
-                                                    GAsyncReadyCallback callback,
-                                                    gpointer user_data)
-{
-       GSimpleAsyncResult *result;
-
-       result = g_simple_async_result_new (G_OBJECT (self),
-                                           callback, user_data,
-                                           empathy_tp_chat_provide_password_finish);
-
-       tp_cli_channel_interface_password_call_provide_password
-               ((TpChannel *) self, -1, password, provide_password_cb, result,
-                NULL, G_OBJECT (self));
-}
-
-gboolean
-empathy_tp_chat_provide_password_finish (EmpathyTpChat *self,
-                                                     GAsyncResult *result,
-                                                     GError **error)
-{
-       if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
-               error))
-               return FALSE;
-
-       g_return_val_if_fail (g_simple_async_result_is_valid (result,
-                                                             G_OBJECT (self), empathy_tp_chat_provide_password_finish), FALSE);
-
-       return TRUE;
-}
-
 /**
  * empathy_tp_chat_can_add_contact:
  *
@@ -1805,15 +1607,6 @@ empathy_tp_chat_get_self_contact (EmpathyTpChat *self)
        return self->priv->user;
 }
 
-
-gboolean
-empathy_tp_chat_is_sms_channel (EmpathyTpChat *self)
-{
-       g_return_val_if_fail (EMPATHY_IS_TP_CHAT (self), FALSE);
-
-       return self->priv->sms_channel;
-}
-
 GQuark
 empathy_tp_chat_get_feature_ready (void)
 {
@@ -1821,28 +1614,26 @@ empathy_tp_chat_get_feature_ready (void)
 }
 
 static void
-conn_prepared_cb (GObject *source,
-       GAsyncResult *result,
+tp_chat_prepare_ready_async (TpProxy *proxy,
+       const TpProxyFeature *feature,
+       GAsyncReadyCallback callback,
        gpointer user_data)
 {
-       EmpathyTpChat *self = user_data;
-       TpChannel *channel = (TpChannel *) self;
-       GError *error = NULL;
-       TpHandle handle;
-       TpConnection *connection = (TpConnection *) source;
+       EmpathyTpChat *self = (EmpathyTpChat *) proxy;
+       TpChannel *channel = (TpChannel *) proxy;
+       TpConnection *connection;
 
-       if (!tp_proxy_prepare_finish (source, result, &error)) {
-               g_simple_async_result_set_from_error (self->priv->ready_result, error);
-               g_error_free (error);
-               g_simple_async_result_complete (self->priv->ready_result);
-               tp_clear_object (&self->priv->ready_result);
-               return;
-       }
+       g_assert (self->priv->ready_result == NULL);
+       self->priv->ready_result = g_simple_async_result_new (G_OBJECT (self),
+               callback, user_data, tp_chat_prepare_ready_async);
+
+       connection = tp_channel_borrow_connection (channel);
 
        if (tp_proxy_has_interface_by_id (self,
                                          TP_IFACE_QUARK_CHANNEL_INTERFACE_GROUP)) {
                const TpIntSet *members;
                GArray *handles;
+               TpHandle handle;
 
                /* Get self contact from the group's self handle */
                handle = tp_channel_group_get_self_handle (channel);
@@ -1865,6 +1656,7 @@ conn_prepared_cb (GObject *source,
                TpCapabilities *caps;
                GPtrArray *classes;
                guint i;
+               TpHandle handle;
 
                /* Get the self contact from the connection's self handle */
                handle = tp_connection_get_self_handle (connection);
@@ -1910,56 +1702,4 @@ conn_prepared_cb (GObject *source,
                                                                               NULL, NULL,
                                                                               G_OBJECT (self), NULL);
        }
-
-       /* Check if the chat is password protected */
-       if (tp_proxy_has_interface_by_id (self,
-                                         TP_IFACE_QUARK_CHANNEL_INTERFACE_PASSWORD)) {
-               self->priv->got_password_flags = FALSE;
-
-               tp_cli_channel_interface_password_connect_to_password_flags_changed
-                       (channel, password_flags_changed_cb, self, NULL,
-                        G_OBJECT (self), NULL);
-
-               tp_cli_channel_interface_password_call_get_password_flags
-                       (channel, -1, got_password_flags_cb, self, NULL, G_OBJECT (self));
-       } else {
-               /* No Password interface, so no need to fetch the password flags */
-               self->priv->got_password_flags = TRUE;
-       }
-
-       /* Check if the chat is for SMS */
-       if (tp_proxy_has_interface_by_id (channel,
-                                         TP_IFACE_QUARK_CHANNEL_INTERFACE_SMS)) {
-               tp_cli_channel_interface_sms_connect_to_sms_channel_changed (
-                       channel,
-                       sms_channel_changed_cb, self, NULL, G_OBJECT (self), NULL);
-
-               tp_cli_dbus_properties_call_get (channel, -1,
-                       TP_IFACE_CHANNEL_INTERFACE_SMS, "SMSChannel",
-                       get_sms_channel_cb, self, NULL, G_OBJECT (self));
-       } else {
-               /* if there's no SMS support, then we're not waiting for it */
-               self->priv->got_sms_channel = TRUE;
-       }
-}
-
-static void
-tp_chat_prepare_ready_async (TpProxy *proxy,
-       const TpProxyFeature *feature,
-       GAsyncReadyCallback callback,
-       gpointer user_data)
-{
-       EmpathyTpChat *self = (EmpathyTpChat *) proxy;
-       TpChannel *channel = (TpChannel *) proxy;
-       TpConnection *connection;
-       GQuark conn_features[] = { TP_CONNECTION_FEATURE_CAPABILITIES, 0 };
-
-       g_assert (self->priv->ready_result == NULL);
-       self->priv->ready_result = g_simple_async_result_new (G_OBJECT (self),
-               callback, user_data, tp_chat_prepare_ready_async);
-
-       connection = tp_channel_borrow_connection (channel);
-
-       tp_proxy_prepare_async (connection, conn_features,
-               conn_prepared_cb, self);
 }