]> git.0d.be Git - empathy.git/commitdiff
Keep track of ``global'' presence of all accounts
authorSjoerd Simons <sjoerd.simons@collabora.co.uk>
Wed, 15 Jul 2009 13:53:29 +0000 (14:53 +0100)
committerSjoerd Simons <sjoerd.simons@collabora.co.uk>
Thu, 16 Jul 2009 11:41:48 +0000 (12:41 +0100)
libempathy/empathy-account-manager.c
libempathy/empathy-account-manager.h
libempathy/empathy-account.c
libempathy/empathy-account.h

index 0795f3ad511b9ee369a8d1e0913c7f18120960e3..dc15651cb3b7717a98762470a1eb8d72f2829f24 100644 (file)
 
 #include "config.h"
 
-#include <libmissioncontrol/mc-account-monitor.h>
 #include <telepathy-glib/util.h>
 #include <telepathy-glib/account-manager.h>
 #include <telepathy-glib/enums.h>
 #include <telepathy-glib/defs.h>
+#include <telepathy-glib/interfaces.h>
 
 #include "empathy-account-manager.h"
 #include "empathy-marshal.h"
@@ -47,6 +47,13 @@ typedef struct {
   TpProxySignalConnection *proxy_signal;
   TpAccountManager *tp_manager;
   TpDBusDaemon *dbus;
+
+  /* global presence */
+  EmpathyAccount *global_account;
+
+  TpConnectionPresenceType global_presence;
+  gchar *global_status;
+  gchar *global_status_message;
 } EmpathyAccountManagerPriv;
 
 enum {
@@ -56,7 +63,7 @@ enum {
   ACCOUNT_DISABLED,
   ACCOUNT_CHANGED,
   ACCOUNT_CONNECTION_CHANGED,
-  ACCOUNT_PRESENCE_CHANGED,
+  GLOBAL_PRESENCE_CHANGED,
   NEW_CONNECTION,
   LAST_SIGNAL
 };
@@ -130,230 +137,110 @@ emp_account_status_changed_cb (EmpathyAccount *account,
 }
 
 static void
-emp_account_presence_changed_cb (EmpathyAccount *account,
-  TpConnectionPresenceType old,
-  TpConnectionPresenceType new,
-  gpointer user_data)
+emp_account_manager_update_global_presence (EmpathyAccountManager *manager)
 {
-  EmpathyAccountManager *manager = EMPATHY_ACCOUNT_MANAGER (user_data);
-  g_signal_emit (manager, signals[ACCOUNT_PRESENCE_CHANGED], 0,
-    account, new, old);
-}
-
-static void
-emp_account_ready_cb (GObject *obj, GParamSpec *spec, gpointer user_data)
-{
-  EmpathyAccountManager *manager = EMPATHY_ACCOUNT_MANAGER (user_data);
-  EmpathyAccount *account = EMPATHY_ACCOUNT (obj);
-  gboolean ready;
-
-  g_object_get (account, "ready", &ready, NULL);
-
-  if (!ready)
-    return;
-
-  g_signal_emit (manager, signals[ACCOUNT_CREATED], 0, account);
-
-  g_signal_connect (account, "notify::connection",
-    G_CALLBACK (emp_account_connection_cb), manager);
-
-  g_signal_connect (account, "notify::enabled",
-    G_CALLBACK (emp_account_enabled_cb), manager);
-
-  g_signal_connect (account, "status-changed",
-    G_CALLBACK (emp_account_status_changed_cb), manager);
-
-  g_signal_connect (account, "presence-changed",
-    G_CALLBACK (emp_account_presence_changed_cb), manager);
-}
-
-static EmpathyAccount *
-create_account (EmpathyAccountManager *manager,
-  const gchar *account_name,
-  McAccount *mc_account)
-{
-#if 0
   EmpathyAccountManagerPriv *priv = GET_PRIV (manager);
-  EmpathyAccount *account;
-  TpConnectionStatus status;
-  TpConnectionPresenceType presence;
-  McPresence mc_presence;
-  TpConnection *connection;
-  GError *error = NULL;
-
-  if ((account = g_hash_table_lookup (priv->accounts, account_name)) != NULL)
-    return account;
-
-  account = _empathy_account_new (mc_account);
-  g_hash_table_insert (priv->accounts, g_strdup (account_name),
-    account);
-
-  _empathy_account_set_enabled (account,
-      mc_account_is_enabled (mc_account));
-
-  g_signal_emit (manager, signals[ACCOUNT_CREATED], 0, account);
-
-  g_signal_connect (account, "notify::connection",
-    G_CALLBACK (emp_account_connection_cb), manager);
+  TpConnectionPresenceType presence = TP_CONNECTION_PRESENCE_TYPE_UNSET;
+  EmpathyAccount *account = NULL;
+  GHashTableIter iter;
+  gpointer value;
 
-  connection = mission_control_get_tpconnection (priv->mc,
-    mc_account, NULL);
-  _empathy_account_set_connection (account, connection);
+  g_hash_table_iter_init (&iter, priv->accounts);
+  while (g_hash_table_iter_next (&iter, NULL, &value))
+    {
+      EmpathyAccount *a = EMPATHY_ACCOUNT (value);
+      TpConnectionPresenceType p;
 
-  status = mission_control_get_connection_status (priv->mc,
-     mc_account, &error);
+      g_object_get (a, "presence", &p, NULL);
 
-  if (error != NULL)
-    {
-      status = TP_CONNECTION_STATUS_DISCONNECTED;
-      g_clear_error (&error);
+      if (tp_connection_presence_type_cmp_availability (p, presence) > 0)
+        {
+          account = a;
+          presence = p;
+        }
     }
 
-  mc_presence = mission_control_get_presence_actual (priv->mc, &error);
-  if (error != NULL)
-    {
-      presence = TP_CONNECTION_PRESENCE_TYPE_UNSET;
-      g_clear_error (&error);
-    }
-  else
+  priv->global_account = account;
+  g_free (priv->global_status);
+  g_free (priv->global_status_message);
+
+  if (account == NULL)
     {
-      presence = mc_presence_to_tp_presence (mc_presence);
+      priv->global_status = NULL;
+      priv->global_status_message = NULL;
+      return;
     }
 
-  g_signal_connect (account, "status-changed",
-    G_CALLBACK (emp_account_status_changed_cb), manager);
-
-  g_signal_connect (account, "presence-changed",
-    G_CALLBACK (emp_account_presence_changed_cb), manager);
-
-  _empathy_account_set_status (account, status,
-    TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED,
-    presence);
-
-  return account;
-#endif
-  return NULL;
-}
-
-#if 0
-static void
-account_created_cb (McAccountMonitor *mon,
-                    gchar *account_name,
-                    EmpathyAccountManager *manager)
-{
-  McAccount *mc_account = mc_account_lookup (account_name);
-
-  if (mc_account != NULL)
-    create_account (manager, account_name, mc_account);
+  g_object_get (account,
+    "presence", &priv->global_presence,
+    "status", &priv->global_status,
+    "status-message", &priv->global_status_message,
+    NULL);
 }
 
 static void
-account_deleted_cb (McAccountMonitor *mon,
-                    gchar *account_name,
-                    EmpathyAccountManager *manager)
+emp_account_presence_changed_cb (EmpathyAccount *account,
+  TpConnectionPresenceType presence,
+  const gchar *status,
+  const gchar *status_message,
+  gpointer user_data)
 {
+  EmpathyAccountManager *manager = EMPATHY_ACCOUNT_MANAGER (user_data);
   EmpathyAccountManagerPriv *priv = GET_PRIV (manager);
-  EmpathyAccount *account;
 
-  account = g_hash_table_lookup (priv->accounts, account_name);
-
-  if (account)
+  if (tp_connection_presence_type_cmp_availability (presence,
+      priv->global_presence) > 0)
     {
-      g_signal_emit (manager, signals[ACCOUNT_DELETED], 0, account);
-      g_hash_table_remove (priv->accounts, account_name);
-    }
-}
-
-static void
-account_changed_cb (McAccountMonitor *mon,
-                    gchar *account_name,
-                    EmpathyAccountManager *manager)
-{
-  EmpathyAccountManagerPriv *priv = GET_PRIV (manager);
-  EmpathyAccount *account;
-
-  account = g_hash_table_lookup (priv->accounts, account_name);
-
-  if (account != NULL)
-    g_signal_emit (manager, signals[ACCOUNT_CHANGED], 0, account);
-}
+      priv->global_account = account;
 
+      priv->global_presence = presence;
 
-typedef struct {
-  TpConnectionStatus status;
-  TpConnectionPresenceType presence;
-  TpConnectionStatusReason reason;
-  gchar *unique_name;
-  EmpathyAccountManager *manager;
-  McAccount *mc_account;
-} ChangedSignalData;
-
-static gboolean
-account_status_changed_idle_cb (ChangedSignalData *signal_data)
-{
-  EmpathyAccount *account;
-  EmpathyAccountManager *manager = signal_data->manager;
-  EmpathyAccountManagerPriv *priv = GET_PRIV (manager);
+      g_free (priv->global_status);
+      priv->global_status = g_strdup (status);
 
-  account = g_hash_table_lookup (priv->accounts,
-    signal_data->unique_name);
+      g_free (priv->global_status_message);
+      priv->global_status_message = g_strdup (status_message);
 
-  if (account)
+      goto signal;
+    }
+  else if (priv->global_account == account)
     {
-      if (empathy_account_get_connection (account) == NULL)
-        {
-          TpConnection *connection;
-
-          connection = mission_control_get_tpconnection (priv->mc,
-             signal_data->mc_account, NULL);
-
-          if (connection != NULL)
-            {
-              _empathy_account_set_connection (account, connection);
-              g_object_unref (connection);
-            }
-        }
-
-      _empathy_account_set_status (account, signal_data->status,
-        signal_data->reason,
-        signal_data->presence);
+      emp_account_manager_update_global_presence (manager);
+      goto signal;
     }
 
-  g_object_unref (signal_data->manager);
-  g_object_unref (signal_data->mc_account);
-  g_free (signal_data->unique_name);
-  g_slice_free (ChangedSignalData, signal_data);
-
-  return FALSE;
+  return;
+signal:
+    g_signal_emit (manager, signals[GLOBAL_PRESENCE_CHANGED], 0,
+      priv->global_presence, priv->global_status, priv->global_status_message);
 }
-#endif
 
-#if 0
 static void
-account_status_changed_cb (MissionControl *mc,
-                           TpConnectionStatus status,
-                           McPresence presence,
-                           TpConnectionStatusReason reason,
-                           const gchar *unique_name,
-                           EmpathyAccountManager *manager)
+emp_account_ready_cb (GObject *obj, GParamSpec *spec, gpointer user_data)
 {
-  ChangedSignalData *data;
+  EmpathyAccountManager *manager = EMPATHY_ACCOUNT_MANAGER (user_data);
+  EmpathyAccount *account = EMPATHY_ACCOUNT (obj);
+  gboolean ready;
+
+  g_object_get (account, "ready", &ready, NULL);
+
+  if (!ready)
+    return;
+
+  g_signal_emit (manager, signals[ACCOUNT_CREATED], 0, account);
 
-  DEBUG ("Status of account %s became "
-    "status: %d presence: %d reason: %d", unique_name, status,
-    presence, reason);
+  g_signal_connect (account, "notify::connection",
+    G_CALLBACK (emp_account_connection_cb), manager);
+
+  g_signal_connect (account, "notify::enabled",
+    G_CALLBACK (emp_account_enabled_cb), manager);
 
-  data = g_slice_new0 (ChangedSignalData);
-  data->status = status;
-  data->presence = mc_presence_to_tp_presence (presence);
-  data->reason = reason;
-  data->unique_name = g_strdup (unique_name);
-  data->manager = g_object_ref (manager);
-  data->mc_account = mc_account_lookup (unique_name);
+  g_signal_connect (account, "status-changed",
+    G_CALLBACK (emp_account_status_changed_cb), manager);
 
-  g_idle_add ((GSourceFunc) account_status_changed_idle_cb, data);
+  g_signal_connect (account, "presence-changed",
+    G_CALLBACK (emp_account_presence_changed_cb), manager);
 }
-#endif
 
 static void
 account_manager_got_all_cb (TpProxy *proxy,
@@ -424,6 +311,7 @@ empathy_account_manager_init (EmpathyAccountManager *manager)
 
   manager->priv = priv;
   priv->connected = priv->connecting = 0;
+  priv->global_presence = TP_CONNECTION_PRESENCE_TYPE_UNSET;
 
   priv->accounts = g_hash_table_new_full (g_str_hash, g_str_equal,
       g_free, (GDestroyNotify) g_object_unref);
@@ -575,17 +463,17 @@ empathy_account_manager_class_init (EmpathyAccountManagerClass *klass)
                   G_TYPE_UINT,  /* actual connection */
                   G_TYPE_UINT); /* previous connection */
 
-  signals[ACCOUNT_PRESENCE_CHANGED] =
-    g_signal_new ("account-presence-changed",
+  signals[GLOBAL_PRESENCE_CHANGED] =
+    g_signal_new ("global-presence-changed",
                   G_TYPE_FROM_CLASS (klass),
                   G_SIGNAL_RUN_LAST,
                   0,
                   NULL, NULL,
-                  _empathy_marshal_VOID__OBJECT_INT_INT,
+                  _empathy_marshal_VOID__UINT_STRING_STRING,
                   G_TYPE_NONE,
-                  3, EMPATHY_TYPE_ACCOUNT,
-                  G_TYPE_INT,  /* actual presence */
-                  G_TYPE_INT); /* previous presence */
+                  3, G_TYPE_UINT, /* Presence type */
+                  G_TYPE_STRING,  /* status */
+                  G_TYPE_STRING); /* stauts message*/
 
   signals[NEW_CONNECTION] =
     g_signal_new ("new-connection",
@@ -786,3 +674,19 @@ empathy_account_manager_request_global_presence (
     }
 }
 
+TpConnectionPresenceType
+empathy_account_manager_get_global_presence (
+  EmpathyAccountManager *manager,
+  gchar **status,
+  gchar **message)
+{
+  EmpathyAccountManagerPriv *priv = GET_PRIV (manager);
+
+  if (status != NULL)
+    *status = g_strdup (priv->global_status);
+  if (message != NULL)
+    *message = g_strdup (priv->global_status_message);
+
+  return priv->global_presence;
+}
+
index d940e6b890c40da8740c5814dfda43f1da7a6ff1..bbf091997c531639467bf64fffcbce2225d57277 100644 (file)
@@ -84,6 +84,11 @@ void empathy_account_manager_request_global_presence (
   const gchar *status,
   const gchar *message);
 
+TpConnectionPresenceType empathy_account_manager_get_global_presence (
+  EmpathyAccountManager *manager,
+  gchar **status,
+  gchar **message);
+
 G_END_DECLS
 
 #endif /* __EMPATHY_ACCOUNT_MANAGER_H__ */
index d965fac62d6a7c54ab11b5e17c0fecaaf8e18810..5bfa38765af0ab51a0a520890ff1e5b7a0b368c9 100644 (file)
@@ -27,6 +27,7 @@
 #include <telepathy-glib/account.h>
 #include <telepathy-glib/gtypes.h>
 #include <telepathy-glib/util.h>
+#include <telepathy-glib/interfaces.h>
 
 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
 #include <libempathy/empathy-debug.h>
@@ -50,6 +51,8 @@ static guint signals[LAST_SIGNAL];
 enum {
   PROP_ENABLED = 1,
   PROP_PRESENCE,
+  PROP_STATUS,
+  PROP_STATUS_MESSAGE,
   PROP_READY,
   PROP_CONNECTION_STATUS,
   PROP_CONNECTION_STATUS_REASON,
@@ -71,9 +74,12 @@ struct _EmpathyAccountPriv
   TpConnection *connection;
   guint connection_invalidated_id;
 
-  TpConnectionStatus status;
+  TpConnectionStatus connection_status;
   TpConnectionStatusReason reason;
+
   TpConnectionPresenceType presence;
+  gchar *status;
+  gchar *message;
 
   gboolean enabled;
   gboolean valid;
@@ -108,7 +114,7 @@ empathy_account_init (EmpathyAccount *obj)
 
   obj->priv = priv;
 
-  priv->status = TP_CONNECTION_STATUS_DISCONNECTED;
+  priv->connection_status = TP_CONNECTION_STATUS_DISCONNECTED;
 }
 
 static void
@@ -157,8 +163,14 @@ empathy_account_get_property (GObject *object,
       case PROP_PRESENCE:
         g_value_set_uint (value, priv->presence);
         break;
+      case PROP_STATUS:
+        g_value_set_string (value, priv->status);
+        break;
+      case PROP_STATUS_MESSAGE:
+        g_value_set_string (value, priv->message);
+        break;
       case PROP_CONNECTION_STATUS:
-        g_value_set_uint (value, priv->status);
+        g_value_set_uint (value, priv->connection_status);
         break;
       case PROP_CONNECTION_STATUS_REASON:
         g_value_set_uint (value, priv->reason);
@@ -191,11 +203,12 @@ empathy_account_update (EmpathyAccount *account, GHashTable *properties)
   EmpathyAccountPriv *priv = GET_PRIV (account);
   const gchar *conn_path;
   GValueArray *arr;
-  TpConnectionStatus old_s = priv->status;
-  TpConnectionPresenceType old_p = priv->presence;
+  TpConnectionStatus old_s = priv->connection_status;
+  gboolean presence_changed = FALSE;
 
   if (g_hash_table_lookup (properties, "ConnectionStatus") != NULL)
-    priv->status = tp_asv_get_int32 (properties, "ConnectionStatus", NULL);
+    priv->connection_status =
+      tp_asv_get_int32 (properties, "ConnectionStatus", NULL);
 
   if (g_hash_table_lookup (properties, "ConnectionStatusReason") != NULL)
     priv->reason = tp_asv_get_int32 (properties,
@@ -203,9 +216,16 @@ empathy_account_update (EmpathyAccount *account, GHashTable *properties)
 
   if (g_hash_table_lookup (properties, "CurrentPresence") != NULL)
     {
+      presence_changed = TRUE;
       arr = tp_asv_get_boxed (properties, "CurrentPresence",
         TP_STRUCT_TYPE_SIMPLE_PRESENCE);
       priv->presence = g_value_get_uint (g_value_array_get_nth (arr, 0));
+
+      g_free (priv->status);
+      priv->status = g_value_dup_string (g_value_array_get_nth (arr, 1));
+
+      g_free (priv->message);
+      priv->message = g_value_dup_string (g_value_array_get_nth (arr, 2));
     }
 
   if (g_hash_table_lookup (properties, "DisplayName") != NULL)
@@ -236,9 +256,9 @@ empathy_account_update (EmpathyAccount *account, GHashTable *properties)
       g_object_notify (G_OBJECT (account), "ready");
     }
 
-  if (priv->status != old_s)
+  if (priv->connection_status != old_s)
     {
-      if (priv->status == TP_CONNECTION_STATUS_CONNECTED)
+      if (priv->connection_status == TP_CONNECTION_STATUS_CONNECTED)
         {
           GTimeVal val;
           g_get_current_time (&val);
@@ -247,16 +267,18 @@ empathy_account_update (EmpathyAccount *account, GHashTable *properties)
         }
 
       g_signal_emit (account, signals[STATUS_CHANGED], 0,
-        old_s, priv->status, priv->reason);
+        old_s, priv->connection_status, priv->reason);
 
       g_object_notify (G_OBJECT (account), "status");
     }
 
-  if (priv->presence != old_p)
+  if (presence_changed)
     {
       g_signal_emit (account, signals[PRESENCE_CHANGED], 0,
-        old_p, priv->presence);
+        priv->presence, priv->status, priv->message);
       g_object_notify (G_OBJECT (account), "presence");
+      g_object_notify (G_OBJECT (account), "status");
+      g_object_notify (G_OBJECT (account), "status-message");
     }
 
   if (g_hash_table_lookup (properties, "Connection") != NULL)
@@ -417,8 +439,22 @@ empathy_account_class_init (EmpathyAccountClass *empathy_account_class)
       TP_CONNECTION_PRESENCE_TYPE_UNSET,
       G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
 
+  g_object_class_install_property (object_class, PROP_STATUS,
+    g_param_spec_string ("status",
+      "Status",
+      "The Status string of the account",
+      NULL,
+      G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
+
+  g_object_class_install_property (object_class, PROP_STATUS_MESSAGE,
+    g_param_spec_string ("status-message",
+      "status-message",
+      "The Status message string of the account",
+      NULL,
+      G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
+
   g_object_class_install_property (object_class, PROP_CONNECTION_STATUS,
-    g_param_spec_uint ("status",
+    g_param_spec_uint ("connection-status",
       "ConnectionStatus",
       "The accounts connections status type",
       0,
@@ -474,8 +510,8 @@ empathy_account_class_init (EmpathyAccountClass *empathy_account_class)
     G_TYPE_FROM_CLASS (object_class),
     G_SIGNAL_RUN_LAST,
     0, NULL, NULL,
-    _empathy_marshal_VOID__UINT_UINT,
-    G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
+    _empathy_marshal_VOID__UINT_STRING_STRING,
+    G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
 }
 
 void
@@ -508,6 +544,9 @@ empathy_account_finalize (GObject *object)
 {
   EmpathyAccountPriv *priv = GET_PRIV (object);
 
+  g_free (priv->status);
+  g_free (priv->message);
+
   g_free (priv->cm_name);
   g_free (priv->proto_name);
   g_free (priv->icon_name);
@@ -524,7 +563,7 @@ empathy_account_is_just_connected (EmpathyAccount *account)
   EmpathyAccountPriv *priv = GET_PRIV (account);
   GTimeVal val;
 
-  if (priv->status != TP_CONNECTION_STATUS_CONNECTED)
+  if (priv->connection_status != TP_CONNECTION_STATUS_CONNECTED)
     return FALSE;
 
   g_get_current_time (&val);
index 4be35a919e4acd1f92a84e12d05e3c837a4d127b..252c959d25ac6d7222855b39e25bf069d57594fc 100644 (file)
@@ -24,7 +24,6 @@
 #include <glib-object.h>
 
 #include <telepathy-glib/connection.h>
-#include <libmissioncontrol/mc-profile.h>
 
 G_BEGIN_DECLS