static void
empathy_tube_dispatch_name_has_owner_cb (TpDBusDaemon *proxy,
  gboolean has_owner, const GError *error, gpointer user_data,
  GObject *object)
{
  EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
  EmpathyTubeDispatchPriv *priv = GET_PRIV (self);

  if (error != NULL)
    {
      DEBUG ("NameHasOwner failed. Can't dispatch tube");
      empathy_tube_dispatch_set_ability (self,
        EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE);
      return;
    }

  if (has_owner)
    {
      DEBUG ("Tube handler is running. Can dispatch it");
      empathy_tube_dispatch_set_ability (self,
        EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE);
    }
  else
    {
      DEBUG ("Tube handler is not running. Calling ListActivatableNames");
      tp_cli_dbus_daemon_call_list_activatable_names (priv->dbus, -1,
        empathy_tube_dispatch_list_activatable_names_cb, NULL, NULL,
        G_OBJECT (self));
    }
}
static void
empathy_tube_dispatch_name_has_owner_cb (TpDBusDaemon *proxy,
  gboolean has_owner, const GError *error, gpointer user_data,
  GObject *object)
{
  EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
  EmpathyTubeDispatchPriv *priv = GET_PRIV (self);

  if (error != NULL)
    {
      empathy_tube_dispatch_set_ability (self,
        EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE);
      return;
    }

  if (has_owner)
    {
      empathy_tube_dispatch_set_ability (self,
        EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE);
    }
  else
    {
      tp_cli_dbus_daemon_call_list_activatable_names (priv->dbus, -1,
        empathy_tube_dispatch_list_activatable_names_cb, NULL, NULL,
        G_OBJECT (self));
    }
}
static void
empathy_tube_dispatch_constructed (GObject *object)
{
  EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
  EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
  TpChannel *channel;
  GHashTable *properties;
  const gchar *service;
  const gchar *channel_type;
  TpTubeType type;

  priv->dbus = tp_dbus_daemon_new (tp_get_bus());

  channel = empathy_dispatch_operation_get_channel (priv->operation);
  properties = tp_channel_borrow_immutable_properties (channel);

  channel_type = tp_asv_get_string (properties,
    TP_IFACE_CHANNEL ".ChannelType");
  if (channel_type == NULL)
    goto failed;

  if (!tp_strdiff (channel_type, EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE))
    {
      type = TP_TUBE_TYPE_STREAM;
      service = tp_asv_get_string (properties,
        EMP_IFACE_CHANNEL_TYPE_STREAM_TUBE  ".Service");
    }
  else if (!tp_strdiff (channel_type, EMP_IFACE_CHANNEL_TYPE_DBUS_TUBE))
    {
      type = TP_TUBE_TYPE_DBUS;
      service = tp_asv_get_string (properties,
        EMP_IFACE_CHANNEL_TYPE_DBUS_TUBE  ".ServiceName");
    }
  else
    {
      goto failed;
    }


  if (service == NULL)
    goto failed;

  priv->bus_name = empathy_tube_handler_build_bus_name (type, service);
  priv->object_path = empathy_tube_handler_build_object_path (type, service);

  priv->service = g_strdup (service);

  DEBUG ("Look for tube handler %s\n", priv->bus_name);
  tp_cli_dbus_daemon_call_name_has_owner (priv->dbus, -1, priv->bus_name,
    empathy_tube_dispatch_name_has_owner_cb, NULL, NULL, G_OBJECT (self));

  return;

failed:
  empathy_tube_dispatch_set_ability (self,
    EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE);
}
static void
empathy_tube_dispatch_list_activatable_names_cb (TpDBusDaemon *proxy,
  const gchar **names, const GError *error, gpointer user_data,
  GObject *object)
{
  EmpathyTubeDispatch *self = EMPATHY_TUBE_DISPATCH (object);
  EmpathyTubeDispatchPriv *priv = GET_PRIV (self);
  gchar **name;

  for (name = (gchar **) names; *name != NULL; name++)
    {
      if (!tp_strdiff (*name, priv->bus_name))
        {
          empathy_tube_dispatch_set_ability (self,
            EMPATHY_TUBE_DISPATCHABILITY_POSSIBLE);
          return;
        }
    }

  empathy_tube_dispatch_set_ability (self,
    EMPATHY_TUBE_DISPATCHABILITY_IMPOSSIBLE);
}